Files
flxn-app/src/features/teams/components/team-list.tsx
2025-09-25 15:49:09 -05:00

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;