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
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>
|
|
);
|
|
} |