You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
4.0 KiB
TypeScript

import { useState } from 'react';
import TeamPlayerAvatar from './TeamPlayerAvatar';
import { CompactTeamRowProps } from './CompactTeamRow.types';
import { cleanName } from '@/src/utils/bookingUtils';
export default function CompactTeamRow({
players,
currentUserId,
teamColor = 'purple',
size = 'md',
maxDisplay,
displayFilter,
overlapAmount = 'md',
showBubbles = true,
className = '',
onPlayerClick,
emptySpotVariant = 'light'
}: CompactTeamRowProps) {
const [hoveredPlayerId, setHoveredPlayerId] = useState<number | null>(null);
const handlePlayerMouseEnter = (playerId: number | null) => {
if (playerId !== null) {
setHoveredPlayerId(playerId);
}
};
const handlePlayerMouseLeave = () => {
setHoveredPlayerId(null);
};
const handlePlayerClick = (player: any) => {
// Toggle bubble on click for mobile
if (player.remote_member_id !== null) {
if (hoveredPlayerId === player.remote_member_id) {
setHoveredPlayerId(null);
} else {
setHoveredPlayerId(player.remote_member_id);
}
}
if (onPlayerClick) {
onPlayerClick(player);
}
};
// Determine overlap margin based on size and overlapAmount
const getOverlapMargin = () => {
const baseMargins = {
sm: { sm: '-ml-2', md: '-ml-3', lg: '-ml-4' },
md: { sm: '-ml-3', md: '-ml-4', lg: '-ml-5' },
lg: { sm: '-ml-4', md: '-ml-5', lg: '-ml-6' }
};
return baseMargins[size][overlapAmount];
};
const overlapMargin = getOverlapMargin();
// Filter players using displayFilter function if provided
const filteredPlayers = displayFilter
? players.filter(displayFilter)
: players;
// Limit displayed players to maxDisplay if specified
const displayedPlayers = maxDisplay !== undefined
? filteredPlayers.slice(0, maxDisplay)
: filteredPlayers;
const remainingCount = maxDisplay !== undefined
? Math.max(0, filteredPlayers.length - maxDisplay)
: 0;
return (
<div
className={`inline-flex items-center ${className}`}
>
{displayedPlayers.map((player, index) => {
const isCurrentUser = player.remote_member_id !== null && player.remote_member_id === currentUserId;
const isGuest = player.remote_member_id === null || player.full_account_str === 'Invité';
const cleanedName = player.full_account_str ? cleanName(player.full_account_str) : '';
return (
<div
key={player.remote_member_id || `guest-${index}`}
className={`${index > 0 ? overlapMargin : ''}`}
style={{
zIndex: displayedPlayers.length - index,
position: 'relative'
}}
onClick={() => handlePlayerClick(player)}
>
<TeamPlayerAvatar
player={player}
isCurrentUser={isCurrentUser}
isExpanded={false}
isBrilliant={isCurrentUser}
onMouseEnter={() => handlePlayerMouseEnter(player.remote_member_id)}
onMouseLeave={handlePlayerMouseLeave}
teamColor={teamColor}
showBubble={showBubbles && !isGuest && hoveredPlayerId === player.remote_member_id}
bubblePosition="top"
isAnonymous={isGuest || (player.remote_member_id !== null && player.remote_member_id < 0 && player.remote_member_id > -100)}
isJoinRequest={false}
isCoachOrClub={false}
emptySpotVariant={emptySpotVariant}
/>
</div>
);
})}
{remainingCount > 0 && maxDisplay !== undefined && (
<div
className={`${overlapMargin} flex items-center justify-center rounded-full bg-slate-200 text-slate-700 font-medium`}
style={{
zIndex: 0,
width: size === 'sm' ? '32px' : size === 'md' ? '40px' : '48px',
height: size === 'sm' ? '32px' : size === 'md' ? '40px' : '48px',
fontSize: size === 'sm' ? '12px' : size === 'md' ? '14px' : '16px'
}}
>
+{remainingCount}
</div>
)}
</div>
);
}