import { Badge } from '@renderer/components/ui/badge'; import { HoverCard, HoverCardContent, HoverCardTrigger } from '@renderer/components/ui/hover-card'; import { getTeamColorSet, getThemedBadge, getThemedBorder, getThemedText, } from '@renderer/constants/teamColors'; import { useTheme } from '@renderer/hooks/useTheme'; import { useStore } from '@renderer/store'; import { formatAgentRole } from '@renderer/utils/formatAgentRole'; import { agentAvatarUrl, getMemberDotClass, getPresenceLabel } from '@renderer/utils/memberHelpers'; import { ExternalLink } from 'lucide-react'; import { CurrentTaskIndicator } from './CurrentTaskIndicator'; import type { LeadActivityState, TeamTaskWithKanban } from '@shared/types'; interface MemberHoverCardProps { /** The member name to look up */ name: string; /** Color key for the member */ color?: string; /** Called when user clicks on the current task */ onOpenTask?: (task: TeamTaskWithKanban) => void; children: React.ReactNode; } /** * Wraps children in a HoverCard that shows member info on hover. * Reads member data from the store (selectedTeamData.members). * Falls back to a simple wrapper when member data is unavailable. */ export const MemberHoverCard = ({ name, color, onOpenTask, children, }: MemberHoverCardProps): React.JSX.Element => { const { isLight } = useTheme(); const member = useStore((s) => s.selectedTeamData?.members.find((m) => m.name === name) ?? null); const isTeamAlive = useStore((s) => s.selectedTeamData?.isAlive); const teamName = useStore((s) => s.selectedTeamName); const leadActivity: LeadActivityState | undefined = useStore((s) => teamName ? s.leadActivityByTeam[teamName] : undefined ); const openMemberProfile = useStore((s) => s.openMemberProfile); const tasks = useStore((s) => s.selectedTeamData?.tasks); if (!member) { return <>{children}; } const colors = getTeamColorSet(color ?? member.color ?? ''); const roleLabel = formatAgentRole(member.role) ?? formatAgentRole(member.agentType); const presenceLabel = getPresenceLabel( member, isTeamAlive, false, member.agentType === 'team-lead' ? leadActivity : undefined ); const dotClass = getMemberDotClass( member, isTeamAlive, false, member.agentType === 'team-lead' ? leadActivity : undefined ); const currentTask: TeamTaskWithKanban | null = member.currentTaskId && tasks ? (tasks.find((t) => t.id === member.currentTaskId) ?? null) : null; const reviewTask: TeamTaskWithKanban | null = !currentTask && tasks ? (tasks.find( (task) => task.reviewer === member.name && (task.reviewState === 'review' || task.kanbanColumn === 'review') ) ?? null) : null; const activityTask = currentTask ?? reviewTask; const activityLabel = currentTask ? 'working on' : reviewTask ? 'reviewing' : 'working on'; return ( {children}
{/* Header: avatar + name + presence */}
{member.name}
{member.name} {presenceLabel}
{roleLabel && ( {roleLabel} )}
{/* Current task */} {activityTask && (
onOpenTask(activityTask) : undefined} />
)} {/* Open profile button */}
); };