significant refactor

This commit is contained in:
2025-08-30 01:42:23 -05:00
parent 7136f646a3
commit 052f53444e
106 changed files with 1994 additions and 1701 deletions

View File

@@ -1,8 +1,14 @@
import { Autocomplete, Stack, ActionIcon, Text, Group, Loader } from "@mantine/core";
import {
Autocomplete,
Stack,
ActionIcon,
Text,
Group,
Loader,
} from "@mantine/core";
import { TrashIcon } from "@phosphor-icons/react";
import { useQuery } from "@tanstack/react-query";
import { useState, useCallback, useMemo, memo } from "react";
import { tournamentQueries } from "../queries";
import { useTournament, useUnenrolledTeams } from "../queries";
import useEnrollTeam from "../hooks/use-enroll-team";
import useUnenrollTeam from "../hooks/use-unenroll-team";
import Avatar from "@/components/avatar";
@@ -12,13 +18,17 @@ interface EditEnrolledTeamsProps {
tournamentId: string;
}
const TeamItem = memo(({ team, onUnenroll, disabled }: {
interface TeamItemProps {
team: Team;
onUnenroll: (teamId: string) => void;
disabled: boolean;
}) => {
const playerNames = useMemo(() =>
team.players?.map(p => `${p.first_name} ${p.last_name}`).join(", ") || "",
}
const TeamItem = memo(({ team, onUnenroll, disabled }: TeamItemProps) => {
const playerNames = useMemo(
() =>
team.players?.map((p) => `${p.first_name} ${p.last_name}`).join(", ") ||
"",
[team.players]
);
@@ -26,9 +36,13 @@ const TeamItem = memo(({ team, onUnenroll, disabled }: {
<Group py="xs" px="sm" w="100%" gap="sm" align="center">
<Avatar size={32} name={team.name} />
<Stack gap={0} style={{ flex: 1, minWidth: 0 }}>
<Text fw={500} truncate>{team.name}</Text>
<Text fw={500} truncate>
{team.name}
</Text>
{playerNames && (
<Text size="xs" c="dimmed" truncate>{playerNames}</Text>
<Text size="xs" c="dimmed" truncate>
{playerNames}
</Text>
)}
</Stack>
<ActionIcon
@@ -47,30 +61,43 @@ const TeamItem = memo(({ team, onUnenroll, disabled }: {
const EditEnrolledTeams = ({ tournamentId }: EditEnrolledTeamsProps) => {
const [search, setSearch] = useState("");
const { data: tournament, isLoading: tournamentLoading } =
useQuery(tournamentQueries.details(tournamentId));
const { data: unenrolledTeams = [], isLoading: unenrolledLoading } =
useQuery(tournamentQueries.unenrolled(tournamentId));
const { data: tournament, isLoading: tournamentLoading } =
useTournament(tournamentId);
const { data: unenrolledTeams = [], isLoading: unenrolledLoading } =
useUnenrolledTeams(tournamentId);
const { mutate: enrollTeam, isPending: isEnrolling } = useEnrollTeam();
const { mutate: unenrollTeam, isPending: isUnenrolling } = useUnenrollTeam();
const autocompleteData = useMemo(() =>
unenrolledTeams.map((team: Team) => ({ value: team.id, label: team.name })),
const autocompleteData = useMemo(
() =>
unenrolledTeams.map((team: Team) => ({
value: team.id,
label: team.name,
})),
[unenrolledTeams]
);
const handleEnrollTeam = useCallback((teamId: string) => {
enrollTeam({ tournamentId, teamId }, {
onSuccess: () => {
setSearch("");
}
});
}, [enrollTeam, tournamentId, setSearch]);
const handleEnrollTeam = useCallback(
(teamId: string) => {
enrollTeam(
{ tournamentId, teamId },
{
onSuccess: () => {
setSearch("");
},
}
);
},
[enrollTeam, tournamentId, setSearch]
);
const handleUnenrollTeam = useCallback((teamId: string) => {
unenrollTeam({ tournamentId, teamId });
}, [unenrollTeam, tournamentId]);
const handleUnenrollTeam = useCallback(
(teamId: string) => {
unenrollTeam({ tournamentId, teamId });
},
[unenrollTeam, tournamentId]
);
const isLoading = tournamentLoading || unenrolledLoading;
const enrolledTeams = tournament?.teams || [];
@@ -79,7 +106,9 @@ const EditEnrolledTeams = ({ tournamentId }: EditEnrolledTeamsProps) => {
return (
<Stack gap="lg" w="100%">
<Stack gap="xs">
<Text fw={600} size="sm">Add Team</Text>
<Text fw={600} size="sm">
Add Team
</Text>
<Autocomplete
placeholder="Search for teams to enroll..."
data={autocompleteData}
@@ -95,18 +124,26 @@ const EditEnrolledTeams = ({ tournamentId }: EditEnrolledTeamsProps) => {
<Stack gap="xs">
<Group justify="space-between">
<Text fw={600} size="sm">Enrolled Teams</Text>
<Text size="xs" c="dimmed">{enrolledTeams.length} teams</Text>
<Text fw={600} size="sm">
Enrolled Teams
</Text>
<Text size="xs" c="dimmed">
{enrolledTeams.length} teams
</Text>
</Group>
{isLoading ? (
<Group justify="center" py="md"><Loader size="sm" /></Group>
<Group justify="center" py="md">
<Loader size="sm" />
</Group>
) : !hasEnrolledTeams ? (
<Text size="sm" c="dimmed" ta="center" py="lg">No teams enrolled yet</Text>
<Text size="sm" c="dimmed" ta="center" py="lg">
No teams enrolled yet
</Text>
) : (
<Stack gap="xs" w="100%">
{enrolledTeams.map((team: Team) => (
<TeamItem
<TeamItem
key={team.id}
team={team}
onUnenroll={handleUnenrollTeam}