111 lines
2.5 KiB
TypeScript
111 lines
2.5 KiB
TypeScript
import {
|
|
Divider,
|
|
Group,
|
|
List,
|
|
ListItem,
|
|
Skeleton,
|
|
Stack,
|
|
Text,
|
|
} from "@mantine/core";
|
|
import Avatar from "@/components/avatar";
|
|
import { TeamInfo } from "@/features/teams/types";
|
|
import { useNavigate } from "@tanstack/react-router";
|
|
import { useCallback, useMemo } from "react";
|
|
import React from "react";
|
|
|
|
interface TeamListItemProps {
|
|
team: TeamInfo;
|
|
}
|
|
const TeamListItem = React.memo(({ team }: TeamListItemProps) => {
|
|
const playerNames = useMemo(
|
|
() => team.players?.map((p) => `${p.first_name} ${p.last_name}`) || [],
|
|
[team.players]
|
|
);
|
|
|
|
return (
|
|
<Group justify="space-between" w="100%">
|
|
<Text fw={500}>{`${team.name}`}</Text>
|
|
<Stack ml="auto" gap={0}>
|
|
{playerNames.map((name) => (
|
|
<Text size="xs" c="dimmed" ta="right">
|
|
{name}
|
|
</Text>
|
|
))}
|
|
</Stack>
|
|
</Group>
|
|
);
|
|
});
|
|
|
|
interface TeamListProps {
|
|
teams: TeamInfo[];
|
|
loading?: boolean;
|
|
onTeamClick?: (teamId: string) => void;
|
|
}
|
|
|
|
const TeamList = ({ teams, loading = false, onTeamClick }: TeamListProps) => {
|
|
const navigate = useNavigate();
|
|
|
|
const handleClick = useCallback(
|
|
(teamId: string) => {
|
|
if (onTeamClick) {
|
|
onTeamClick(teamId);
|
|
} else {
|
|
navigate({ to: `/teams/${teamId}` });
|
|
}
|
|
},
|
|
[navigate, onTeamClick]
|
|
);
|
|
|
|
if (loading)
|
|
return (
|
|
<List p="0">
|
|
{Array.from({ length: 10 }).map((_, i) => (
|
|
<ListItem
|
|
key={`skeleton-${i}`}
|
|
py="xs"
|
|
icon={<Skeleton height={40} width={40} />}
|
|
>
|
|
<Skeleton height={35} width={200} />
|
|
</ListItem>
|
|
))}
|
|
</List>
|
|
);
|
|
|
|
return (
|
|
<List p="0">
|
|
{teams?.map((team) => (
|
|
<div key={team.id}>
|
|
<ListItem
|
|
key={`team-list-${team.id}`}
|
|
p="xs"
|
|
icon={
|
|
<Avatar
|
|
radius="sm"
|
|
size={40}
|
|
name={`${team.name}`}
|
|
src={
|
|
team.logo
|
|
? `/api/files/teams/${team.id}/${team.logo}`
|
|
: undefined
|
|
}
|
|
/>
|
|
}
|
|
style={{ cursor: "pointer" }}
|
|
onClick={() => handleClick(team.id)}
|
|
styles={{
|
|
itemWrapper: { width: "100%" },
|
|
itemLabel: { width: "100%" },
|
|
}}
|
|
w="100%"
|
|
>
|
|
<TeamListItem team={team} />
|
|
</ListItem>
|
|
<Divider />
|
|
</div>
|
|
))}
|
|
</List>
|
|
);
|
|
};
|
|
|
|
export default TeamList;
|