import React from 'react'; import { Check, Plus, RefreshCcw, Sparkles, UserSearch } from 'lucide-react'; import { useTheme } from '../../contexts/ThemeContext'; import { InlineCollapsible, StageHeader, ThinkingBlock } from './SixStepCards'; import type { ExpertCard, ExpertMatchData } from './types'; interface ExpertCardItemProps { card: ExpertCard; index: number; selected: boolean; disabled?: boolean; onSelect: (id: string) => void; } const renderAvatar = (avatar: string | undefined, fallback: React.ReactNode, isDark: boolean) => { if (avatar && avatar.trim().startsWith(' ); } return ( {fallback} ); }; const ExpertCardItem: React.FC = ({ card, index, selected, disabled, onSelect }) => { const { theme } = useTheme(); const isDark = theme === 'dark'; const baseBorder = selected ? isDark ? 'border-cyan-300/60 ring-1 ring-cyan-300/40 shadow-lg shadow-cyan-500/10 bg-gradient-to-br from-slate-800/70 to-cyan-900/30' : 'border-red-300 ring-1 ring-red-200 shadow-md shadow-red-100 bg-gradient-to-br from-white to-red-50/60' : isDark ? 'border-slate-700/60 bg-gradient-to-br from-slate-800/40 to-slate-900/20 hover:border-cyan-300/40' : 'border-gray-100 bg-white hover:border-red-200'; return ( onSelect(card.id)} className={`w-full text-left rounded-2xl border p-3 transition-all sixstep-fade-up disabled:cursor-not-allowed disabled:opacity-60 ${baseBorder}`} > {index.toString().padStart(2, '0')} {renderAvatar(card.avatarUrl, , isDark)} {card.name} {card.isCustom && ( 新建 )} {card.detail || '暂无描述'} ); }; interface ExpertMatchCardsProps { data: ExpertMatchData; onSelectExpert: (id: string) => void; onRefetch: () => void; onCreateExpert: () => void; onConfirm: () => void; locked?: boolean; } const ExpertMatchCards: React.FC = ({ data, onSelectExpert, onRefetch, onCreateExpert, onConfirm, locked, }) => { const { theme } = useTheme(); const isDark = theme === 'dark'; const isSearching = data.status === 'searching'; const isCreating = data.status === 'creating'; const isReady = data.status === 'ready' || data.status === 'confirmed'; const cards = data.experts ?? []; return ( 0 ? '专家已匹配完成,可选择一位进入下一步' : '正在调用查找专家 MCP...' : isCreating ? '正在调用创建专家 MCP...' : data.status === 'error' ? data.errorMessage || '专家匹配失败' : '请选择一位专家进入下一步' } count={cards.length} loading={(isSearching && cards.length === 0) || isCreating} done={data.status === 'confirmed'} icon={UserSearch} accent="actor" /> } > 推荐专家列表 {cards.length} 位 } > {cards.length === 0 ? ( {isSearching && cards.length === 0 ? '正在匹配专家...' : '暂无匹配的专家'} ) : ( {cards.map((card, idx) => ( ))} )} {data.status === 'error' && ( {data.errorMessage} )} 重新查找 没有想要的专家? 创建专家 选择该专家 ); }; export default ExpertMatchCards;