/ app / src / components / AgentSelector.tsx
AgentSelector.tsx
  1  import React, { useState, KeyboardEvent } from 'react';
  2  import { useApp } from '../contexts/AppContext';
  3  import { mockAgents } from '../data/mockData';
  4  import type { Agent } from '../types';
  5  import './AgentSelector.css';
  6  
  7  const getLevelColor = (level: string): string => {
  8    const colors: Record<string, string> = {
  9      'Master': '#E6E6FA',
 10      'Expert': '#FF6B6B',
 11      'Advanced': '#7B68EE',
 12      'Autonomous': '#FFD700',
 13      'Intermediate': '#888888',
 14      'Basic': '#888888'
 15    };
 16    return colors[level] || '#888888';
 17  };
 18  
 19  export const AgentSelector: React.FC = () => {
 20    const { agentSelectorVisible, hideAgentSelector, selectAgent, addMessage } = useApp();
 21    const [selectedIndex, setSelectedIndex] = useState(0);
 22  
 23    const handleKeyDown = (e: KeyboardEvent) => {
 24      switch (e.key) {
 25        case 'Escape':
 26          hideAgentSelector();
 27          break;
 28        case 'ArrowUp':
 29        case 'k':
 30          e.preventDefault();
 31          setSelectedIndex(prev => Math.max(0, prev - 1));
 32          break;
 33        case 'ArrowDown':
 34        case 'j':
 35          e.preventDefault();
 36          setSelectedIndex(prev => Math.min(mockAgents.length - 1, prev + 1));
 37          break;
 38        case 'Enter':
 39          e.preventDefault();
 40          handleSelect(mockAgents[selectedIndex]);
 41          break;
 42      }
 43    };
 44  
 45    const handleSelect = (agent: Agent) => {
 46      selectAgent(agent);
 47      addMessage({
 48        role: 'system',
 49        content: `Switched to ${agent.name} - ${agent.personality.name}`,
 50        timestamp: new Date()
 51      });
 52      hideAgentSelector();
 53    };
 54  
 55    if (!agentSelectorVisible) return null;
 56  
 57    return (
 58      <div
 59        className="agent-selector-overlay"
 60        onClick={hideAgentSelector}
 61        onKeyDown={handleKeyDown}
 62        tabIndex={0}
 63      >
 64        <div className="agent-selector" onClick={(e) => e.stopPropagation()}>
 65          <div className="selector-header">
 66            <h2>🤖 Select Spirit Agent</h2>
 67            <p className="selector-subtitle">
 68              Choose your specialized agent for the task
 69            </p>
 70          </div>
 71  
 72          <div className="agent-cards">
 73            {mockAgents.map((agent, idx) => (
 74              <div
 75                key={agent.id}
 76                className={`agent-card ${idx === selectedIndex ? 'selected' : ''}`}
 77                onClick={() => handleSelect(agent)}
 78              >
 79                <div className="card-header">
 80                  <span className="card-icon">{agent.icon}</span>
 81                  <span className="card-name">{agent.name}</span>
 82                  <span
 83                    className="card-level"
 84                    style={{ background: getLevelColor(agent.level) }}
 85                  >
 86                    {agent.level}
 87                  </span>
 88                </div>
 89  
 90                <div className="card-info">
 91                  <div className="card-row">
 92                    <span className="info-label">ID:</span>
 93                    <span className="info-value">{agent.id}</span>
 94                    <span className="info-separator">•</span>
 95                    <span className="info-label">Type:</span>
 96                    <span className="info-value">{agent.type}</span>
 97                  </div>
 98                </div>
 99  
100                <div className="card-personality">
101                  <span className="personality-icon">💭</span>
102                  <span className="personality-text">
103                    "{agent.personality.name}" - {agent.personality.approach}
104                  </span>
105                </div>
106  
107                <div className="card-traits">
108                  <span className="trait-icon">✨</span>
109                  {agent.personality.traits.slice(0, 3).map((trait, i) => (
110                    <span key={i} className="trait-badge">{trait}</span>
111                  ))}
112                </div>
113  
114                <div className="card-specialties">
115                  <span className="specialty-icon">🎯</span>
116                  <span className="specialty-text">
117                    {agent.personality.specialties.slice(0, 2).join(', ')}
118                  </span>
119                </div>
120  
121                <div className="card-capabilities">
122                  <span className="capability-icon">🔧</span>
123                  <span className="capability-text">
124                    {agent.capabilities.length} capabilities
125                  </span>
126                </div>
127              </div>
128            ))}
129          </div>
130  
131          <div className="selector-footer">
132            ↑↓/j/k Navigate • ENTER Select • ESC Cancel
133          </div>
134        </div>
135      </div>
136    );
137  };