Merge branch 'style' into development
This commit is contained in:
@@ -10,6 +10,7 @@ import { tournamentKeys } from "@/features/tournaments/queries";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import { MatchForm } from "@/features/bracket/components/match-form";
|
||||
import TeamAvatar from "@/components/team-avatar";
|
||||
import AnimatedScore from "@/features/matches/components/animated-score";
|
||||
|
||||
interface GroupMatchCardProps {
|
||||
match: Match;
|
||||
@@ -104,14 +105,13 @@ const GroupMatchCard: React.FC<GroupMatchCardProps> = ({ match, showControls })
|
||||
</Text>
|
||||
</Group>
|
||||
{isEnded && match.home_cups !== undefined && (
|
||||
<Text
|
||||
<AnimatedScore
|
||||
value={match.home_cups}
|
||||
size="xl"
|
||||
fw={700}
|
||||
c={homeWon ? "green" : "dimmed"}
|
||||
style={{ minWidth: 32, textAlign: 'center' }}
|
||||
>
|
||||
{match.home_cups}
|
||||
</Text>
|
||||
/>
|
||||
)}
|
||||
</Group>
|
||||
|
||||
@@ -135,14 +135,13 @@ const GroupMatchCard: React.FC<GroupMatchCardProps> = ({ match, showControls })
|
||||
</Text>
|
||||
</Group>
|
||||
{isEnded && match.away_cups !== undefined && (
|
||||
<Text
|
||||
<AnimatedScore
|
||||
value={match.away_cups}
|
||||
size="xl"
|
||||
fw={700}
|
||||
c={awayWon ? "green" : "dimmed"}
|
||||
style={{ minWidth: 32, textAlign: 'center' }}
|
||||
>
|
||||
{match.away_cups}
|
||||
</Text>
|
||||
/>
|
||||
)}
|
||||
</Group>
|
||||
</Stack>
|
||||
@@ -152,6 +151,7 @@ const GroupMatchCard: React.FC<GroupMatchCardProps> = ({ match, showControls })
|
||||
{showStartButton && (
|
||||
<ActionIcon
|
||||
color="green"
|
||||
aria-label="Start match"
|
||||
onClick={handleStartMatch}
|
||||
loading={start.isPending}
|
||||
size="md"
|
||||
@@ -170,6 +170,7 @@ const GroupMatchCard: React.FC<GroupMatchCardProps> = ({ match, showControls })
|
||||
{showEditButton && (
|
||||
<ActionIcon
|
||||
color="blue"
|
||||
aria-label="Edit match score"
|
||||
onClick={editSheet.open}
|
||||
size="md"
|
||||
h="100%"
|
||||
@@ -191,6 +192,7 @@ const GroupMatchCard: React.FC<GroupMatchCardProps> = ({ match, showControls })
|
||||
match={match}
|
||||
onSubmit={handleFormSubmit}
|
||||
onCancel={editSheet.close}
|
||||
loading={end.isPending}
|
||||
/>
|
||||
</Sheet>
|
||||
)}
|
||||
|
||||
@@ -367,7 +367,11 @@ const GroupStageView: React.FC<GroupStageViewProps> = ({
|
||||
<Text fw={600} size="sm">
|
||||
Standings ({standings.length})
|
||||
</Text>
|
||||
<ActionIcon variant="subtle" size="sm">
|
||||
<ActionIcon
|
||||
variant="subtle"
|
||||
size="sm"
|
||||
aria-label={expandedTeams[group.id] ? "Collapse standings" : "Expand standings"}
|
||||
>
|
||||
{expandedTeams[group.id] ? <CaretCircleUpIcon size={16} /> : <CaretCircleDownIcon size={16} />}
|
||||
</ActionIcon>
|
||||
</MantineGroup>
|
||||
|
||||
@@ -1,101 +1,145 @@
|
||||
import { Stack, Group, Text, ThemeIcon, Box, Center } from "@mantine/core";
|
||||
import { Stack, Group, Text, ThemeIcon } from "@mantine/core";
|
||||
import { CrownIcon, MedalIcon } from "@phosphor-icons/react";
|
||||
import { TeamInfo } from "@/features/teams/types";
|
||||
import { Tournament } from "../types";
|
||||
|
||||
interface PodiumProps {
|
||||
tournament: Tournament;
|
||||
}
|
||||
|
||||
type PodiumTier = "first" | "second" | "third";
|
||||
|
||||
const tierStyles: Record<PodiumTier, React.CSSProperties> = {
|
||||
first: {
|
||||
background:
|
||||
"light-dark(color-mix(in srgb, var(--mantine-color-yellow-4) 10%, var(--mantine-color-white)), color-mix(in srgb, var(--mantine-color-yellow-8) 16%, var(--mantine-color-dark-6)))",
|
||||
border:
|
||||
"1px solid light-dark(color-mix(in srgb, var(--mantine-color-yellow-6) 45%, var(--mantine-color-gray-3)), color-mix(in srgb, var(--mantine-color-yellow-6) 35%, var(--mantine-color-dark-4)))",
|
||||
borderRadius: "var(--mantine-radius-md)",
|
||||
boxShadow: "var(--mantine-shadow-md)",
|
||||
},
|
||||
second: {
|
||||
background:
|
||||
"light-dark(color-mix(in srgb, var(--mantine-color-gray-5) 10%, var(--mantine-color-white)), color-mix(in srgb, var(--mantine-color-gray-5) 10%, var(--mantine-color-dark-6)))",
|
||||
border:
|
||||
"1px solid light-dark(var(--mantine-color-gray-4), var(--mantine-color-dark-4))",
|
||||
borderRadius: "var(--mantine-radius-md)",
|
||||
boxShadow: "var(--mantine-shadow-xs)",
|
||||
},
|
||||
third: {
|
||||
background:
|
||||
"light-dark(color-mix(in srgb, var(--mantine-color-orange-5) 8%, var(--mantine-color-white)), color-mix(in srgb, var(--mantine-color-orange-9) 14%, var(--mantine-color-dark-6)))",
|
||||
border:
|
||||
"1px solid light-dark(color-mix(in srgb, var(--mantine-color-orange-6) 35%, var(--mantine-color-gray-3)), color-mix(in srgb, var(--mantine-color-orange-7) 30%, var(--mantine-color-dark-4)))",
|
||||
borderRadius: "var(--mantine-radius-md)",
|
||||
boxShadow: "var(--mantine-shadow-xs)",
|
||||
},
|
||||
};
|
||||
|
||||
const tierConfig: Record<
|
||||
PodiumTier,
|
||||
{
|
||||
color: string;
|
||||
label: string;
|
||||
labelColor: string;
|
||||
icon: React.ReactNode;
|
||||
iconSize: "xl" | "lg";
|
||||
padding: "md" | "xs";
|
||||
nameSize: "md" | "sm";
|
||||
}
|
||||
> = {
|
||||
first: {
|
||||
color: "yellow",
|
||||
label: "Champions",
|
||||
labelColor:
|
||||
"light-dark(var(--mantine-color-yellow-8), var(--mantine-color-yellow-4))",
|
||||
icon: <CrownIcon size={24} />,
|
||||
iconSize: "xl",
|
||||
padding: "md",
|
||||
nameSize: "md",
|
||||
},
|
||||
second: {
|
||||
color: "gray",
|
||||
label: "2nd place",
|
||||
labelColor:
|
||||
"light-dark(var(--mantine-color-gray-6), var(--mantine-color-gray-4))",
|
||||
icon: <MedalIcon size={20} />,
|
||||
iconSize: "lg",
|
||||
padding: "xs",
|
||||
nameSize: "sm",
|
||||
},
|
||||
third: {
|
||||
color: "orange",
|
||||
label: "3rd place",
|
||||
labelColor:
|
||||
"light-dark(var(--mantine-color-orange-8), var(--mantine-color-orange-4))",
|
||||
icon: <MedalIcon size={18} />,
|
||||
iconSize: "lg",
|
||||
padding: "xs",
|
||||
nameSize: "sm",
|
||||
},
|
||||
};
|
||||
|
||||
const PodiumRow = ({ team, tier }: { team: TeamInfo; tier: PodiumTier }) => {
|
||||
const config = tierConfig[tier];
|
||||
|
||||
return (
|
||||
<Group gap="md" p={config.padding} style={tierStyles[tier]}>
|
||||
<ThemeIcon
|
||||
size={config.iconSize}
|
||||
color={config.color}
|
||||
variant="light"
|
||||
radius="xl"
|
||||
>
|
||||
{config.icon}
|
||||
</ThemeIcon>
|
||||
<Stack gap={4} style={{ flex: 1 }}>
|
||||
<Text size={config.nameSize} fw={tier === "first" ? 700 : 600}>
|
||||
{team.name}
|
||||
</Text>
|
||||
<Group gap="xs">
|
||||
{team.players?.map((player) => (
|
||||
<Text
|
||||
key={player.id}
|
||||
size={tier === "first" ? "sm" : "xs"}
|
||||
c="dimmed"
|
||||
>
|
||||
{player.first_name} {player.last_name}
|
||||
</Text>
|
||||
))}
|
||||
</Group>
|
||||
</Stack>
|
||||
<Text
|
||||
size="10px"
|
||||
fw={700}
|
||||
tt="uppercase"
|
||||
style={{
|
||||
letterSpacing: "0.08em",
|
||||
alignSelf: "flex-start",
|
||||
color: config.labelColor,
|
||||
}}
|
||||
mt={4}
|
||||
mr={4}
|
||||
>
|
||||
{config.label}
|
||||
</Text>
|
||||
</Group>
|
||||
);
|
||||
};
|
||||
|
||||
export const Podium = ({ tournament }: PodiumProps) => {
|
||||
if (!tournament.first_place) return;
|
||||
|
||||
return (
|
||||
<Stack gap="xs" px="md">
|
||||
{tournament.first_place && (
|
||||
<Group
|
||||
gap="md"
|
||||
p="md"
|
||||
style={{
|
||||
backgroundColor: 'var(--mantine-color-yellow-light)',
|
||||
borderRadius: 'var(--mantine-radius-md)',
|
||||
border: '3px solid var(--mantine-color-yellow-outline)',
|
||||
boxShadow: 'var(--mantine-shadow-md)',
|
||||
}}
|
||||
>
|
||||
<ThemeIcon size="xl" color="yellow" variant="light" radius="xl">
|
||||
<CrownIcon size={24} />
|
||||
</ThemeIcon>
|
||||
<Stack gap={4} style={{ flex: 1 }}>
|
||||
<Text size="md" fw={600}>
|
||||
{tournament.first_place.name}
|
||||
</Text>
|
||||
<Group gap="xs">
|
||||
{tournament.first_place.players?.map((player) => (
|
||||
<Text key={player.id} size="sm" c="dimmed">
|
||||
{player.first_name} {player.last_name}
|
||||
</Text>
|
||||
))}
|
||||
</Group>
|
||||
</Stack>
|
||||
</Group>
|
||||
<PodiumRow team={tournament.first_place} tier="first" />
|
||||
)}
|
||||
|
||||
{tournament.second_place && (
|
||||
<Group
|
||||
gap="md"
|
||||
p="xs"
|
||||
style={{
|
||||
backgroundColor: 'var(--mantine-color-default)',
|
||||
borderRadius: 'var(--mantine-radius-md)',
|
||||
border: '2px solid var(--mantine-color-default-border)',
|
||||
boxShadow: 'var(--mantine-shadow-sm)',
|
||||
}}
|
||||
>
|
||||
<ThemeIcon size="lg" color="gray" variant="light" radius="xl">
|
||||
<MedalIcon size={20} />
|
||||
</ThemeIcon>
|
||||
<Stack gap={4} style={{ flex: 1 }}>
|
||||
<Text size="sm" fw={600}>
|
||||
{tournament.second_place.name}
|
||||
</Text>
|
||||
<Group gap="xs">
|
||||
{tournament.second_place.players?.map((player) => (
|
||||
<Text key={player.id} size="xs" c="dimmed">
|
||||
{player.first_name} {player.last_name}
|
||||
</Text>
|
||||
))}
|
||||
</Group>
|
||||
</Stack>
|
||||
</Group>
|
||||
<PodiumRow team={tournament.second_place} tier="second" />
|
||||
)}
|
||||
|
||||
{tournament.third_place && (
|
||||
<Group
|
||||
gap="md"
|
||||
p="xs"
|
||||
style={{
|
||||
backgroundColor: 'var(--mantine-color-orange-light)',
|
||||
borderRadius: 'var(--mantine-radius-md)',
|
||||
border: '2px solid var(--mantine-color-orange-outline)',
|
||||
boxShadow: 'var(--mantine-shadow-sm)',
|
||||
}}
|
||||
>
|
||||
<ThemeIcon size="lg" color="orange" variant="light" radius="xl">
|
||||
<MedalIcon size={18} />
|
||||
</ThemeIcon>
|
||||
<Stack gap={4} style={{ flex: 1 }}>
|
||||
<Text size="sm" fw={600}>
|
||||
{tournament.third_place.name}
|
||||
</Text>
|
||||
<Group gap="xs">
|
||||
{tournament.third_place.players?.map((player) => (
|
||||
<Text key={player.id} size="xs" c="dimmed">
|
||||
{player.first_name} {player.last_name}
|
||||
</Text>
|
||||
))}
|
||||
</Group>
|
||||
</Stack>
|
||||
</Group>
|
||||
<PodiumRow team={tournament.third_place} tier="third" />
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
|
||||
@@ -1,26 +1,89 @@
|
||||
import { Box, Flex, Loader } from "@mantine/core";
|
||||
import { Box, Divider, Group, Paper, Skeleton, Stack } from "@mantine/core";
|
||||
import SwipeableTabs from "@/components/swipeable-tabs";
|
||||
import TeamList from "@/features/teams/components/team-list";
|
||||
import HeaderSkeleton from "./header-skeleton";
|
||||
|
||||
const SkeletonLoader = () => (
|
||||
<Flex h="30vh" w="100%" align="center" justify="center">
|
||||
<Loader />
|
||||
</Flex>
|
||||
)
|
||||
const MatchCardSkeleton = ({ opacity = 1 }: { opacity?: number }) => (
|
||||
<Paper px="md" py="md" withBorder radius="md" style={{ opacity }}>
|
||||
<Stack gap="sm">
|
||||
<Skeleton height={12} width="55%" radius="sm" />
|
||||
{[0, 1].map((row) => (
|
||||
<Group key={row} justify="space-between" align="center" wrap="nowrap">
|
||||
<Group gap="sm" wrap="nowrap" style={{ flex: 1 }}>
|
||||
<Skeleton height={40} width={40} radius="sm" />
|
||||
<Skeleton height={14} width="40%" radius="sm" />
|
||||
</Group>
|
||||
<Skeleton height={12} width={64} radius="sm" />
|
||||
</Group>
|
||||
))}
|
||||
</Stack>
|
||||
</Paper>
|
||||
);
|
||||
|
||||
const MatchListSkeleton = ({ count = 4 }: { count?: number }) => (
|
||||
<Stack p="md" gap="sm">
|
||||
{Array.from({ length: count }).map((_, index) => (
|
||||
<MatchCardSkeleton
|
||||
key={`match-skeleton-${index}`}
|
||||
opacity={Math.max(1 - index * 0.15, 0.4)}
|
||||
/>
|
||||
))}
|
||||
</Stack>
|
||||
);
|
||||
|
||||
const ResultRowSkeleton = ({ opacity = 1 }: { opacity?: number }) => (
|
||||
<Box p="md" style={{ opacity }}>
|
||||
<Group gap="sm" align="center" wrap="nowrap">
|
||||
<Skeleton height={40} width={40} radius="sm" />
|
||||
<Stack gap={8} style={{ flex: 1 }}>
|
||||
<Skeleton height={14} width="45%" radius="sm" />
|
||||
<Group gap="md" wrap="nowrap">
|
||||
{Array.from({ length: 6 }).map((_, index) => (
|
||||
<Skeleton key={`result-stat-${index}`} height={20} width={22} radius="sm" />
|
||||
))}
|
||||
</Group>
|
||||
</Stack>
|
||||
</Group>
|
||||
</Box>
|
||||
);
|
||||
|
||||
const OverviewSkeleton = () => (
|
||||
<Stack gap="md">
|
||||
<Box>
|
||||
<Group p="md" wrap="nowrap" w="100%">
|
||||
<Skeleton height={20} width={20} radius="sm" />
|
||||
<Skeleton height={16} width={110} radius="sm" />
|
||||
<Skeleton ml="auto" height={20} width={20} radius="sm" />
|
||||
</Group>
|
||||
<Divider />
|
||||
</Box>
|
||||
<Stack gap={0}>
|
||||
<Box px="md" pb="xs">
|
||||
<Skeleton height={18} width={70} radius="sm" />
|
||||
</Box>
|
||||
{Array.from({ length: 4 }).map((_, index) => (
|
||||
<Box key={`result-row-${index}`}>
|
||||
<ResultRowSkeleton opacity={Math.max(1 - index * 0.15, 0.4)} />
|
||||
{index < 3 && <Divider />}
|
||||
</Box>
|
||||
))}
|
||||
</Stack>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
const ProfileSkeleton = () => {
|
||||
const tabs = [
|
||||
{
|
||||
label: "Overview",
|
||||
content: <SkeletonLoader />,
|
||||
content: <OverviewSkeleton />,
|
||||
},
|
||||
{
|
||||
label: "Matches",
|
||||
content: <SkeletonLoader />,
|
||||
content: <MatchListSkeleton />,
|
||||
},
|
||||
{
|
||||
label: "Teams",
|
||||
content: <SkeletonLoader />,
|
||||
content: <TeamList teams={[]} loading />,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -2,10 +2,11 @@ import { useAuth } from "@/contexts/auth-context";
|
||||
import { useTournaments } from "../queries";
|
||||
import { useSheet } from "@/hooks/use-sheet";
|
||||
import { Button, Stack } from "@mantine/core";
|
||||
import { PlusIcon } from "@phosphor-icons/react";
|
||||
import { PlusIcon, TrophyIcon } from "@phosphor-icons/react";
|
||||
import Sheet from "@/components/sheet/sheet";
|
||||
import TournamentForm from "./tournament-form";
|
||||
import { TournamentCard } from "./tournament-card";
|
||||
import EmptyState from "@/components/empty-state";
|
||||
|
||||
const TournamentCardList = () => {
|
||||
const { data: tournaments } = useTournaments();
|
||||
@@ -27,9 +28,17 @@ const TournamentCardList = () => {
|
||||
</Sheet>
|
||||
</>
|
||||
) : null}
|
||||
{tournaments?.map((tournament: any) => (
|
||||
<TournamentCard key={tournament.id} tournament={tournament} />
|
||||
))}
|
||||
{tournaments && tournaments.length > 0 ? (
|
||||
tournaments.map((tournament: any) => (
|
||||
<TournamentCard key={tournament.id} tournament={tournament} />
|
||||
))
|
||||
) : (
|
||||
<EmptyState
|
||||
icon={<TrophyIcon size={32} />}
|
||||
title="No Tournaments Yet"
|
||||
description="The cups are racked and waiting. Check back soon."
|
||||
/>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -20,6 +20,27 @@ interface TournamentCardProps {
|
||||
tournament: TournamentInfo;
|
||||
}
|
||||
|
||||
const tournamentCardCss = `
|
||||
.flxn-tournament-card {
|
||||
transition: border-color 160ms ease-out, box-shadow 160ms ease-out;
|
||||
}
|
||||
@media (hover: hover) {
|
||||
.flxn-tournament-card.flxn-tournament-card:hover {
|
||||
border-color: color-mix(in srgb, var(--mantine-primary-color-filled) 40%, var(--mantine-color-default-border));
|
||||
box-shadow: var(--mantine-shadow-sm);
|
||||
}
|
||||
}
|
||||
.flxn-tournament-card.flxn-tournament-card:active {
|
||||
border-color: color-mix(in srgb, var(--mantine-primary-color-filled) 55%, var(--mantine-color-default-border));
|
||||
box-shadow: none;
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.flxn-tournament-card {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const TournamentCard = ({ tournament }: TournamentCardProps) => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
@@ -29,15 +50,15 @@ export const TournamentCard = ({ tournament }: TournamentCardProps) => {
|
||||
onClick={() => navigate({ to: `/tournaments/${tournament.id}` })}
|
||||
style={{ borderRadius: "var(--mantine-radius-md)" }}
|
||||
>
|
||||
<style href="flxn-tournament-card" precedence="medium">
|
||||
{tournamentCardCss}
|
||||
</style>
|
||||
<Card
|
||||
withBorder
|
||||
radius="md"
|
||||
p="lg"
|
||||
w="100%"
|
||||
style={{
|
||||
transition: "all 0.15s ease",
|
||||
border: "1px solid var(--mantine-color-default-border)",
|
||||
}}
|
||||
className="flxn-tournament-card"
|
||||
>
|
||||
<Group justify="space-between" align="center">
|
||||
<Group gap="md" align="center">
|
||||
|
||||
@@ -2,7 +2,7 @@ import { List, ListItem, Divider, Skeleton, Text, Group, Box, ThemeIcon, Stack }
|
||||
import { useNavigate } from "@tanstack/react-router";
|
||||
import Avatar from "@/components/avatar";
|
||||
import { TournamentInfo } from "../types";
|
||||
import { useCallback } from "react";
|
||||
import { Fragment, useCallback } from "react";
|
||||
import React from "react";
|
||||
import { TrophyIcon, CalendarIcon, MapPinIcon } from "@phosphor-icons/react";
|
||||
|
||||
@@ -99,9 +99,8 @@ const TournamentList = ({ tournaments, loading = false }: TournamentListProps) =
|
||||
return (
|
||||
<List p="0">
|
||||
{tournaments.map((tournament) => (
|
||||
<>
|
||||
<Fragment key={tournament.id}>
|
||||
<ListItem
|
||||
key={tournament.id}
|
||||
p="xs"
|
||||
icon={
|
||||
<Avatar
|
||||
@@ -129,7 +128,7 @@ const TournamentList = ({ tournaments, loading = false }: TournamentListProps) =
|
||||
<TournamentListItem tournament={tournament} />
|
||||
</ListItem>
|
||||
<Divider />
|
||||
</>
|
||||
</Fragment>
|
||||
))}
|
||||
</List>
|
||||
);
|
||||
|
||||
@@ -98,7 +98,7 @@ const EnrolledFreeAgent: React.FC<{ tournamentId: string, isRegional?: boolean }
|
||||
{freeAgents
|
||||
.filter(agent => agent.player)
|
||||
.map((agent) => (
|
||||
<Group key={agent.id} justify="space-between" align="center" wrap="nowrap" p="xs" style={{ borderRadius: '8px', backgroundColor: 'var(--mantine-color-gray-0)' }}>
|
||||
<Group key={agent.id} justify="space-between" align="center" wrap="nowrap" p="xs" style={{ borderRadius: '8px', backgroundColor: 'var(--mantine-color-default-hover)' }}>
|
||||
<Text size="sm" fw={500} truncate>
|
||||
{agent.player?.first_name} {agent.player?.last_name}
|
||||
</Text>
|
||||
@@ -107,6 +107,7 @@ const EnrolledFreeAgent: React.FC<{ tournamentId: string, isRegional?: boolean }
|
||||
<ActionIcon
|
||||
variant="subtle"
|
||||
size="sm"
|
||||
aria-label="Copy phone number"
|
||||
onClick={() => copyToClipboard(agent.phone!)}
|
||||
style={{ cursor: 'pointer' }}
|
||||
>
|
||||
|
||||
@@ -55,7 +55,16 @@ const UpcomingTournament: React.FC<{ tournament: Tournament }> = ({
|
||||
<Stack px="xs">
|
||||
{tournament.desc && <Text px="md" ta="center" size="sm" style={{ whiteSpace: 'pre-wrap' }}>{tournament.desc}</Text>}
|
||||
|
||||
<Card withBorder radius="lg" p="lg">
|
||||
<Card
|
||||
withBorder
|
||||
radius="lg"
|
||||
p="lg"
|
||||
style={{
|
||||
borderTop: "3px solid var(--mantine-primary-color-filled)",
|
||||
backgroundImage:
|
||||
"linear-gradient(to bottom, var(--mantine-primary-color-light), transparent 110px)",
|
||||
}}
|
||||
>
|
||||
<Stack gap="xs">
|
||||
<Group gap="xs" align="center">
|
||||
<UsersIcon size={16} />
|
||||
|
||||
@@ -13,7 +13,7 @@ interface UnenrollTeamProps {
|
||||
|
||||
const UnenrollTeam = ({ tournamentId, teamId, onSubmit }: UnenrollTeamProps) => {
|
||||
const { open, isOpen, toggle } = useSheet();
|
||||
const { mutate: unenrollTeam } = useUnenrollTeam();
|
||||
const { mutate: unenrollTeam, isPending } = useUnenrollTeam();
|
||||
const handleUnenrollTeam = useCallback(
|
||||
async () => {
|
||||
await unenrollTeam({ tournamentId, teamId }, {
|
||||
@@ -35,8 +35,8 @@ const UnenrollTeam = ({ tournamentId, teamId, onSubmit }: UnenrollTeamProps) =>
|
||||
<Sheet title={"Unenroll Team"} opened={isOpen} onChange={toggle}>
|
||||
<Stack gap='xs'>
|
||||
<Text size="sm" fw={500}>Are you sure you want to unenroll from this tournament? You can enroll again at any point before the deadline.</Text>
|
||||
<Button onClick={handleUnenrollTeam}>Confirm</Button>
|
||||
<Button variant="subtle" color="red" onClick={toggle}>Cancel</Button>
|
||||
<Button onClick={handleUnenrollTeam} loading={isPending}>Confirm</Button>
|
||||
<Button variant="subtle" color="red" onClick={toggle} disabled={isPending}>Cancel</Button>
|
||||
</Stack>
|
||||
</Sheet>
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user