Spaces:
Running
Running
| import { useState, useEffect } from 'react' | |
| import { Shield, Zap, Eye, Volume2, Video, Search, Lightbulb, CheckCircle, AlertCircle } from 'lucide-react' | |
| const agentIcons = { | |
| 'text-analyzer': Search, | |
| 'image-processor': Eye, | |
| 'audio-guard': Volume2, | |
| 'video-shield': Video, | |
| 'security-auditor': Shield, | |
| 'creative-solver': Lightbulb | |
| } | |
| const statusColors = { | |
| active: 'text-green-500', | |
| monitoring: 'text-yellow-500', | |
| idle: 'text-gray-500' | |
| } | |
| export default function AgentSelector({ onAgentSelect, selectedAgent }) { | |
| const [agents, setAgents] = useState([]) | |
| const [loading, setLoading] = useState(true) | |
| useEffect(() => { | |
| fetchAgents() | |
| }, []) | |
| const fetchAgents = async () => { | |
| try { | |
| const response = await fetch('/api/agents/status') | |
| const data = await response.json() | |
| setAgents(data.agents) | |
| } catch (error) { | |
| console.error('Failed to fetch agents:', error) | |
| } finally { | |
| setLoading(false) | |
| } | |
| } | |
| if (loading) { | |
| return ( | |
| <div className="card"> | |
| <div className="animate-pulse space-y-4"> | |
| <div className="h-4 bg-dark-300 dark:bg-dark-600 rounded w-3/4"></div> | |
| <div className="h-4 bg-dark-300 dark:bg-dark-600 rounded w-1/2"></div> | |
| </div> | |
| </div> | |
| ) | |
| } | |
| return ( | |
| <div className="card"> | |
| <h2 className="text-2xl font-bold mb-6 flex items-center"> | |
| <Zap className="mr-2 h-6 w-6 text-primary-500" /> | |
| Agent Selection | |
| </h2> | |
| <div className="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
| {agents.map((agent) => { | |
| const Icon = agentIcons[agent.id] || Shield | |
| return ( | |
| <button | |
| key={agent.id} | |
| onClick={() => onAgentSelect(agent)} | |
| className={`p-4 rounded-lg border-2 transition-all duration-200 text-left ${ | |
| selectedAgent?.id === agent.id | |
| ? 'border-primary-500 bg-primary-50 dark:bg-primary-900/20' | |
| : 'border-dark-300 dark:border-dark-600 hover:border-dark-400 dark:hover:border-dark-500' | |
| }`} | |
| > | |
| <div className="flex items-start justify-between mb-2"> | |
| <div className="flex items-center space-x-3"> | |
| <Icon className="h-5 w-5 text-primary-500" /> | |
| <h3 className="font-semibold">{agent.name}</h3> | |
| </div> | |
| {agent.status === 'active' ? ( | |
| <CheckCircle className={`h-4 w-4 ${statusColors.active}`} /> | |
| ) : ( | |
| <AlertCircle className={`h-4 w-4 ${statusColors.monitoring}`} /> | |
| )} | |
| </div> | |
| <p className="text-sm text-dark-600 dark:text-dark-400 mb-2">{agent.type}</p> | |
| <div className="flex flex-wrap gap-1"> | |
| {agent.capabilities.slice(0, 2).map((cap, idx) => ( | |
| <span | |
| key={idx} | |
| className="text-xs px-2 py-1 bg-dark-100 dark:bg-dark-700 rounded-full" | |
| > | |
| {cap} | |
| </span> | |
| ))} | |
| </div> | |
| </button> | |
| ) | |
| })} | |
| </div> | |
| </div> | |
| ) | |
| } |