import { Stack, ActionIcon, Text, Group, Loader, Box, Button as MantineButton, } from "@mantine/core"; import Typeahead, { TypeaheadOption } from "@/components/typeahead"; import { TrashIcon, PencilIcon, MusicNotesIcon } from "@phosphor-icons/react"; import { useState, useCallback, useMemo, memo } from "react"; import { Trans, Plural, useLingui } from "@lingui/react/macro"; import { useNavigate } from "@tanstack/react-router"; import { useTournament, useUnenrolledTeams } from "../../queries"; import useEnrollTeam from "../../hooks/use-enroll-team"; import useUnenrollTeam from "../../hooks/use-unenroll-team"; import TeamAvatar from "@/components/team-avatar"; import { Team, TeamInfo } from "@/features/teams/types"; import Sheet from "@/components/sheet/sheet"; import TeamForm from "@/features/teams/components/team-form"; import { useTeam } from "@/features/teams/queries"; import { useSheet } from "@/hooks/use-sheet"; interface TeamSectionProps { tournamentId: string; } interface TeamItemProps { team: TeamInfo; onUnenroll: (teamId: string) => void; onEdit: (teamId: string) => void; disabled: boolean; isRegional?: boolean; } const TeamItem = memo(({ team, onUnenroll, onEdit, disabled, isRegional }: TeamItemProps) => { const playerNames = useMemo( () => team.players?.map((p) => `${p.first_name} ${p.last_name}`).join(", ") || "", [team.players] ); return ( {team.name} {playerNames && ( {playerNames} )} onEdit(team.id)} size="sm" > onUnenroll(team.id)} disabled={disabled} size="sm" > ); }); interface TeamEditSheetProps { teamId: string; isOpen: boolean; onClose: () => void; } const TeamEditSheet = ({ teamId, isOpen, onClose }: TeamEditSheetProps) => { const { data: team } = useTeam(teamId); const { t } = useLingui(); return ( {team && ( p.id) : [], logo: typeof team.logo === "string" ? undefined : team.logo, }} close={onClose} /> )} ); }; const TeamSection = ({ tournamentId }: TeamSectionProps) => { const { t } = useLingui(); const navigate = useNavigate(); const { data: tournament, isLoading: tournamentLoading } = useTournament(tournamentId); const { data: unenrolledTeams = [], isLoading: unenrolledLoading } = useUnenrolledTeams(tournamentId); const isRegional = tournament?.regional; const { mutate: enrollTeam, isPending: isEnrolling } = useEnrollTeam(); const { mutate: unenrollTeam, isPending: isUnenrolling } = useUnenrollTeam(); const [selectedTeamId, setSelectedTeamId] = useState(null); const { isOpen: editTeamOpened, open: openEditTeam, close: closeEditTeam, } = useSheet(); const handleEditTeam = useCallback( (teamId: string) => { setSelectedTeamId(teamId); openEditTeam(); }, [openEditTeam] ); const handleCloseEditTeam = useCallback(() => { setSelectedTeamId(null); closeEditTeam(); }, [closeEditTeam]); const searchTeams = async (query: string): Promise[]> => { if (!query.trim()) return []; const filtered = unenrolledTeams.filter((team: Team) => team.name.toLowerCase().includes(query.toLowerCase()) ); return filtered.map((team: Team) => ({ id: team.id, data: team })); }; const handleEnrollTeam = useCallback( (option: TypeaheadOption) => { enrollTeam({ tournamentId, teamId: option.data.id }); }, [enrollTeam, tournamentId] ); const handleUnenrollTeam = useCallback( (teamId: string) => { unenrollTeam({ tournamentId, teamId }); }, [unenrollTeam, tournamentId] ); const renderTeamOption = (option: TypeaheadOption) => { const team = option.data; return ( {team.name} ); }; const formatTeam = (option: TypeaheadOption) => { return option.data.name; }; const isLoading = tournamentLoading || unenrolledLoading; const enrolledTeams = tournament?.teams || []; const hasEnrolledTeams = enrolledTeams.length > 0; return ( <> Add Team } onClick={() => navigate({ to: `/admin/tournaments/${tournamentId}/teams` }) } > Manage Team Songs/Logos Enrolled Teams {isLoading ? ( ) : !hasEnrolledTeams ? ( No teams enrolled yet ) : ( {enrolledTeams.map((team: TeamInfo) => ( ))} )} {selectedTeamId && ( )} ); }; export default TeamSection;