import { useMemo, useState } from 'react'; import { Button } from '@renderer/components/ui/button'; import { Dialog, DialogContent, DialogFooter, DialogHeader } from '@renderer/components/ui/dialog'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@renderer/components/ui/tabs'; import { useMemberStats } from '@renderer/hooks/useMemberStats'; import { BarChart3, FileText, ListPlus, MessageSquare, UserMinus } from 'lucide-react'; import { MemberDetailHeader } from './MemberDetailHeader'; import { MemberDetailStats, type MemberDetailTab } from './MemberDetailStats'; import { MemberLogsTab } from './MemberLogsTab'; import { MemberMessagesTab } from './MemberMessagesTab'; import { MemberStatsTab } from './MemberStatsTab'; import { MemberTasksTab } from './MemberTasksTab'; import type { InboxMessage, LeadActivityState, ResolvedTeamMember, TeamTaskWithKanban, } from '@shared/types'; interface MemberDetailDialogProps { open: boolean; member: ResolvedTeamMember | null; teamName: string; tasks: TeamTaskWithKanban[]; messages: InboxMessage[]; isTeamAlive?: boolean; isTeamProvisioning?: boolean; leadActivity?: LeadActivityState; onClose: () => void; onSendMessage: () => void; onAssignTask: () => void; onTaskClick: (task: TeamTaskWithKanban) => void; onRemoveMember?: () => void; onUpdateRole?: (memberName: string, role: string | undefined) => Promise | void; updatingRole?: boolean; onViewMemberChanges?: (memberName: string, filePath?: string) => void; } export const MemberDetailDialog = ({ open, member, teamName, tasks, messages, isTeamAlive, isTeamProvisioning, leadActivity, onClose, onSendMessage, onAssignTask, onTaskClick, onRemoveMember, onUpdateRole, updatingRole, onViewMemberChanges, }: MemberDetailDialogProps): React.JSX.Element | null => { const memberTasks = useMemo( () => (member ? tasks.filter((t) => t.owner === member.name) : []), [tasks, member] ); const memberMessages = useMemo( () => (member ? messages.filter((m) => m.from === member.name || m.to === member.name) : []), [messages, member] ); const inProgressTasks = useMemo( () => memberTasks.filter((t) => t.status === 'in_progress').length, [memberTasks] ); const completedTasks = useMemo( () => memberTasks.filter((t) => t.status === 'completed').length, [memberTasks] ); const [activeTab, setActiveTab] = useState('tasks'); const { stats: memberStats, loading: statsLoading, error: statsError, } = useMemberStats(teamName, member?.name ?? null); const totalTokens = memberStats ? memberStats.inputTokens + memberStats.outputTokens : null; if (!member) return null; return ( !nextOpen && onClose()}>
onUpdateRole(member.name, newRole) : undefined } updatingRole={updatingRole} />
setActiveTab(v as MemberDetailTab)} className="min-w-0 overflow-hidden" > Tasks {memberTasks.length > 0 && ( {memberTasks.length} )} Messages {memberMessages.length > 0 && ( {memberMessages.length} )} Stats Logs onViewMemberChanges?.(member.name, filePath)} onShowAllFiles={() => onViewMemberChanges?.(member.name)} /> {member.removedAt ? ( Removed {new Date(member.removedAt).toLocaleDateString()} ) : ( <> {onRemoveMember && member.agentType !== 'team-lead' && ( )} )}
); };