regionals enrollments
This commit is contained in:
@@ -5,13 +5,12 @@ import { useSheet } from "@/hooks/use-sheet";
|
||||
import { Stack, Text } from "@mantine/core";
|
||||
import useEnrollFreeAgent from "../../hooks/use-enroll-free-agent";
|
||||
|
||||
const EnrollFreeAgent = ({ tournamentId }: {tournamentId: string} ) => {
|
||||
const EnrollFreeAgent = ({ tournamentId, isRegional }: {tournamentId: string, isRegional?: boolean} ) => {
|
||||
const { open, isOpen, toggle } = useSheet();
|
||||
const { user, phone } = useAuth();
|
||||
|
||||
const { mutate: enrollFreeAgent, isPending: isEnrolling } = useEnrollFreeAgent();
|
||||
const { mutate: enrollFreeAgent, isPending: isEnrolling } = useEnrollFreeAgent(isRegional);
|
||||
const handleEnroll = () => {
|
||||
console.log('enrolling...')
|
||||
enrollFreeAgent({ playerId: user!.id, tournamentId, phone }, {
|
||||
onSuccess: () => {
|
||||
toggle();
|
||||
@@ -22,21 +21,31 @@ const EnrollFreeAgent = ({ tournamentId }: {tournamentId: string} ) => {
|
||||
return (
|
||||
<>
|
||||
<Button variant="subtle" size="sm" onClick={open}>
|
||||
Enroll As Free Agent
|
||||
{isRegional ? "Enroll" : "Enroll As Free Agent"}
|
||||
</Button>
|
||||
|
||||
<Sheet title="Free Agent Enrollment" opened={isOpen} onChange={toggle}>
|
||||
<Sheet title={isRegional ? "Enrollment" : "Free Agent Enrollment"} opened={isOpen} onChange={toggle}>
|
||||
<Stack gap="xs">
|
||||
<Text size="md">
|
||||
Enrolling as a free agent adds you to a pool of players looking for teammates.
|
||||
</Text>
|
||||
<Text size="sm" c='dimmed'>
|
||||
Once enrolled, you can view other free agents and their phone number in order to coordinate teams and walkout songs.
|
||||
</Text>
|
||||
<Text size="xs" c="dimmed">
|
||||
Important: Enrolling as a free agent does not guarantee a tournament spot. To secure a spot, one team member must register through the app and select a walkout song.
|
||||
</Text>
|
||||
<Button onClick={handleEnroll}>Confirm</Button>
|
||||
{isRegional ? (
|
||||
<>
|
||||
<Text size="md">
|
||||
Enroll in this regional tournament to be assigned a random partner.
|
||||
</Text>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Text size="md">
|
||||
Enrolling as a free agent adds you to a pool of players looking for teammates.
|
||||
</Text>
|
||||
<Text size="sm" c='dimmed'>
|
||||
Once enrolled, you can view other free agents and their phone number in order to coordinate teams and walkout songs.
|
||||
</Text>
|
||||
<Text size="xs" c="dimmed">
|
||||
Important: Enrolling as a free agent does not guarantee a tournament spot. To secure a spot, one team member must register through the app and select a walkout song.
|
||||
</Text>
|
||||
</>
|
||||
)}
|
||||
<Button onClick={handleEnroll} loading={isEnrolling}>Confirm</Button>
|
||||
<Button variant="subtle" color="red" onClick={toggle}>Cancel</Button>
|
||||
</Stack>
|
||||
</Sheet>
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
import { Group, Stack, Text, Card, Badge, Box, ActionIcon } from "@mantine/core";
|
||||
import { UserIcon, PhoneIcon } from "@phosphor-icons/react";
|
||||
import { PhoneIcon, CheckCircleIcon } from "@phosphor-icons/react";
|
||||
import { useFreeAgents } from "../../queries";
|
||||
import UnenrollFreeAgent from "./unenroll-free-agent";
|
||||
import toast from "@/lib/sonner";
|
||||
import { useAuth } from "@/contexts/auth-context";
|
||||
import PlayerAvatar from "@/components/player-avatar";
|
||||
|
||||
const EnrolledFreeAgent: React.FC<{ tournamentId: string }> = ({
|
||||
tournamentId
|
||||
const EnrolledFreeAgent: React.FC<{ tournamentId: string, isRegional?: boolean }> = ({
|
||||
tournamentId,
|
||||
isRegional
|
||||
}) => {
|
||||
const { data: freeAgents } = useFreeAgents(tournamentId);
|
||||
const { user } = useAuth();
|
||||
|
||||
const copyToClipboard = async (phone: string) => {
|
||||
try {
|
||||
@@ -38,33 +42,66 @@ const EnrolledFreeAgent: React.FC<{ tournamentId: string }> = ({
|
||||
}
|
||||
};
|
||||
|
||||
if (isRegional) {
|
||||
return (
|
||||
<Stack gap="sm">
|
||||
<Card withBorder radius="md" p="md">
|
||||
<Group justify="space-between" align="center" wrap="nowrap">
|
||||
<Group gap="md" align="center">
|
||||
<PlayerAvatar name={`${user?.first_name} ${user?.last_name}`} size={48} />
|
||||
<Box>
|
||||
<Text size="sm" fw={600}>
|
||||
{user?.first_name} {user?.last_name}
|
||||
</Text>
|
||||
<Group gap={4} align="center">
|
||||
<CheckCircleIcon size={14} weight="fill" color="var(--mantine-color-green-6)" />
|
||||
<Text size="xs" c="green" fw={500}>
|
||||
Enrolled
|
||||
</Text>
|
||||
</Group>
|
||||
</Box>
|
||||
</Group>
|
||||
</Group>
|
||||
</Card>
|
||||
|
||||
<Text size="xs" c="dimmed" ta="center">
|
||||
Partners will be randomly assigned when enrollment closes
|
||||
</Text>
|
||||
|
||||
<UnenrollFreeAgent tournamentId={tournamentId} isRegional={isRegional} />
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack gap="md">
|
||||
<Group justify="space-between" align="center">
|
||||
<Group gap="xs" align="center">
|
||||
<UserIcon size={16} />
|
||||
<Text size="sm" fw={500}>
|
||||
Enrolled as Free Agent
|
||||
</Text>
|
||||
</Group>
|
||||
</Group>
|
||||
<Stack gap="sm">
|
||||
<Text size="sm" fw={600} c="green">
|
||||
✓ Enrolled as Free Agent
|
||||
</Text>
|
||||
|
||||
<Text size="xs" c="dimmed">
|
||||
You're on the free agent list. Other free agents looking for teams:
|
||||
Other players looking for teammates:
|
||||
</Text>
|
||||
|
||||
{freeAgents.length > 1 ? (
|
||||
<Card withBorder radius="md" p="sm">
|
||||
<Stack gap="xs">
|
||||
<Group gap="xs" align="center">
|
||||
<Text size="xs" fw={500} c="dimmed">
|
||||
Free Agents
|
||||
</Text>
|
||||
<Badge variant="light" size="xs" color="blue">
|
||||
{freeAgents.length}
|
||||
</Badge>
|
||||
</Group>
|
||||
|
||||
<Stack gap="xs">
|
||||
{freeAgents
|
||||
.filter(agent => agent.player)
|
||||
.map((agent) => (
|
||||
<Group key={agent.id} justify="space-between" align="center" wrap="nowrap">
|
||||
<Box style={{ flex: 1, minWidth: 0 }}>
|
||||
<Text size="sm" fw={500} truncate>
|
||||
{agent.player?.first_name} {agent.player?.last_name}
|
||||
</Text>
|
||||
</Box>
|
||||
<Group key={agent.id} justify="space-between" align="center" wrap="nowrap" p="xs" style={{ borderRadius: '8px', backgroundColor: 'var(--mantine-color-gray-0)' }}>
|
||||
<Text size="sm" fw={500} truncate>
|
||||
{agent.player?.first_name} {agent.player?.last_name}
|
||||
</Text>
|
||||
{agent.phone && (
|
||||
<Group gap={4} align="center" style={{ flexShrink: 0 }}>
|
||||
<ActionIcon
|
||||
@@ -87,27 +124,15 @@ const EnrolledFreeAgent: React.FC<{ tournamentId: string }> = ({
|
||||
)}
|
||||
</Group>
|
||||
))}
|
||||
|
||||
{freeAgents.length > 1 && (
|
||||
<Badge
|
||||
variant="light"
|
||||
size="xs"
|
||||
color="blue"
|
||||
style={{ alignSelf: 'flex-start', marginTop: '4px' }}
|
||||
>
|
||||
{freeAgents.length} free agents total
|
||||
</Badge>
|
||||
)}
|
||||
</Stack>
|
||||
</Card>
|
||||
</Stack>
|
||||
) : (
|
||||
<Card withBorder radius="md" p="sm">
|
||||
<Text size="sm" c="dimmed" ta="center">
|
||||
You're the only free agent so far
|
||||
</Text>
|
||||
</Card>
|
||||
<Text size="xs" c="dimmed" py="sm">
|
||||
You're the first free agent!
|
||||
</Text>
|
||||
)}
|
||||
<UnenrollFreeAgent tournamentId={tournamentId} />
|
||||
|
||||
<UnenrollFreeAgent tournamentId={tournamentId} isRegional={isRegional} />
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
import ListButton from "@/components/list-button";
|
||||
import Sheet from "@/components/sheet/sheet";
|
||||
import { useSheet } from "@/hooks/use-sheet";
|
||||
import { UserListIcon } from "@phosphor-icons/react";
|
||||
import { useMemo } from "react";
|
||||
import { useFreeAgents } from "../../queries";
|
||||
import { Text } from "@mantine/core";
|
||||
import PlayerList from "@/features/players/components/player-list";
|
||||
import { Player } from "@/features/players/types";
|
||||
|
||||
interface EnrolledPlayersListButtonProps {
|
||||
tournamentId: string;
|
||||
}
|
||||
|
||||
const EnrolledPlayersListButton: React.FC<EnrolledPlayersListButtonProps> = ({ tournamentId }) => {
|
||||
const { data: freeAgents } = useFreeAgents(tournamentId);
|
||||
const count = useMemo(() => freeAgents.length, [freeAgents]);
|
||||
const { open, isOpen, toggle } = useSheet();
|
||||
|
||||
const players = useMemo(() =>
|
||||
freeAgents.map(agent => agent.player).filter((player): player is Player => player !== undefined),
|
||||
[freeAgents]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ListButton
|
||||
label={`View Enrolled Players (${count})`}
|
||||
Icon={UserListIcon}
|
||||
onClick={open}
|
||||
/>
|
||||
|
||||
<Sheet title="Enrolled Players" opened={isOpen} onChange={toggle}>
|
||||
{count === 0 ? (
|
||||
<Text size="sm" c="dimmed" ta="center" py="xl">
|
||||
No players enrolled yet
|
||||
</Text>
|
||||
) : (
|
||||
<PlayerList players={players} />
|
||||
)}
|
||||
</Sheet>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default EnrolledPlayersListButton;
|
||||
@@ -1,14 +1,14 @@
|
||||
import { Suspense, useCallback, useMemo } from "react";
|
||||
import { Suspense, useMemo } from "react";
|
||||
import { Tournament } from "../../types";
|
||||
import { useAuth } from "@/contexts/auth-context";
|
||||
import { Box, Button, Card, Divider, Group, Stack, Text, Title } from "@mantine/core";
|
||||
import { Box, Card, Divider, Group, Stack, Text, Title } from "@mantine/core";
|
||||
import Countdown from "@/components/countdown";
|
||||
import ListLink from "@/components/list-link";
|
||||
import ListButton from "@/components/list-button";
|
||||
import { TreeStructureIcon, UsersIcon } from "@phosphor-icons/react";
|
||||
import EnrollTeam from "./enroll-team";
|
||||
import EnrollFreeAgent from "./enroll-free-agent";
|
||||
import TeamListButton from "./team-list-button";
|
||||
import EnrolledPlayersListButton from "./enrolled-players-list-button";
|
||||
import Header from "./header";
|
||||
import TeamCardSkeleton from "@/features/teams/components/team-card-skeleton";
|
||||
import TeamCard from "@/features/teams/components/team-card";
|
||||
@@ -80,12 +80,19 @@ const UpcomingTournament: React.FC<{ tournament: Tournament }> = ({
|
||||
|
||||
{!isUserEnrolled && isEnrollmentOpen && !isFreeAgent && (
|
||||
<>
|
||||
<EnrollTeam
|
||||
{!tournament.regional && (
|
||||
<>
|
||||
<EnrollTeam
|
||||
tournamentId={tournament.id}
|
||||
onSubmit={handleSubmit}
|
||||
/>
|
||||
<Divider my={0} label="or" />
|
||||
</>
|
||||
)}
|
||||
<EnrollFreeAgent
|
||||
tournamentId={tournament.id}
|
||||
onSubmit={handleSubmit}
|
||||
isRegional={tournament.regional}
|
||||
/>
|
||||
<Divider my={0} label="or" />
|
||||
<EnrollFreeAgent tournamentId={tournament.id} />
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -107,7 +114,10 @@ const UpcomingTournament: React.FC<{ tournament: Tournament }> = ({
|
||||
|
||||
{
|
||||
isFreeAgent && isEnrollmentOpen && (
|
||||
<EnrolledFreeAgent tournamentId={tournament.id} />
|
||||
<EnrolledFreeAgent
|
||||
tournamentId={tournament.id}
|
||||
isRegional={tournament.regional}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -130,7 +140,11 @@ const UpcomingTournament: React.FC<{ tournament: Tournament }> = ({
|
||||
Icon={TreeStructureIcon}
|
||||
disabled
|
||||
/>
|
||||
<TeamListButton teams={tournament.teams || []} />
|
||||
{tournament.regional === true ? (
|
||||
<EnrolledPlayersListButton tournamentId={tournament.id} />
|
||||
) : (
|
||||
<TeamListButton teams={tournament.teams || []} />
|
||||
)}
|
||||
<RulesListButton tournamentId={tournament.id} />
|
||||
</Box>
|
||||
</Stack>
|
||||
|
||||
@@ -5,11 +5,11 @@ import { useSheet } from "@/hooks/use-sheet";
|
||||
import { Stack, Text } from "@mantine/core";
|
||||
import useUnenrollFreeAgent from "../../hooks/use-unenroll-free-agent";
|
||||
|
||||
const UnenrollFreeAgent = ({ tournamentId }: {tournamentId: string} ) => {
|
||||
const UnenrollFreeAgent = ({ tournamentId, isRegional }: {tournamentId: string, isRegional?: boolean} ) => {
|
||||
const { open, isOpen, toggle } = useSheet();
|
||||
const { user } = useAuth();
|
||||
|
||||
const { mutate: unenrollFreeAgent, isPending: isEnrolling } = useUnenrollFreeAgent();
|
||||
const { mutate: unenrollFreeAgent, isPending: isEnrolling } = useUnenrollFreeAgent(isRegional);
|
||||
const handleUnenroll = () => {
|
||||
unenrollFreeAgent({ playerId: user!.id, tournamentId }, {
|
||||
onSuccess: () => {
|
||||
@@ -20,17 +20,21 @@ const UnenrollFreeAgent = ({ tournamentId }: {tournamentId: string} ) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button variant="subtle" size="sm" onClick={open}>
|
||||
<Button variant="subtle" size="sm" color="red" onClick={open}>
|
||||
Unenroll
|
||||
</Button>
|
||||
|
||||
<Sheet title="Are you sure?" opened={isOpen} onChange={toggle}>
|
||||
<Sheet title="Unenroll from tournament?" opened={isOpen} onChange={toggle}>
|
||||
<Stack gap="xs">
|
||||
<Text size="md">
|
||||
This will remove you from the free agent list.
|
||||
{isRegional
|
||||
? "This will remove you from the tournament enrollment."
|
||||
: "This will remove you from the free agent list."}
|
||||
</Text>
|
||||
<Button onClick={handleUnenroll}>Confirm</Button>
|
||||
<Button variant="subtle" color="red" onClick={toggle}>Cancel</Button>
|
||||
<Button color="red" onClick={handleUnenroll} loading={isEnrolling}>
|
||||
Confirm Unenrollment
|
||||
</Button>
|
||||
<Button variant="subtle" onClick={toggle}>Cancel</Button>
|
||||
</Stack>
|
||||
</Sheet>
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user