import { useState, useEffect, useRef } from 'react'; import _rwsProjects from 'react-use-websocket'; const useWebSocket = (() => { if (typeof _rwsProjects === 'function') return _rwsProjects; const a = _rwsProjects as any; if (typeof a?.default === 'function') return a.default; if (typeof a?.useWebSocket === 'function') return a.useWebSocket; return _rwsProjects; })() as typeof _rwsProjects; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; import type { Project, Expert, DiscussionMessage } from '../types'; import { t } from '../i18n'; const WS_URL = '/ws'; const EXPERT_COLORS = [ 'text-blue-400', 'text-green-400', 'text-purple-400', 'text-orange-400', ]; const CLI_BADGE_COLORS: Record = { claude: 'bg-blue-900/50 text-blue-300 border border-blue-700', codex: 'bg-green-900/50 text-green-300 border border-green-700', gemini: 'bg-yellow-900/50 text-yellow-300 border border-yellow-700', }; const MODE_ICONS: Record = { roundtable: '🏛️', debate: '⚔️', relay: '🔄', auto: '🤖', }; const STATUS_BADGE: Record = { setup: 'bg-gray-700 text-gray-300', discussing: 'bg-blue-900/50 text-blue-300', discussed: 'bg-purple-900/50 text-purple-300', concluded: 'bg-green-900/50 text-green-300', }; function expertColor(index: number): string { return EXPERT_COLORS[index % EXPERT_COLORS.length]; } function cliBadge(cli: string): string { return CLI_BADGE_COLORS[cli] ?? 'bg-gray-700 text-gray-300 border border-gray-600'; } // ---- New Project Form ---- interface NewProjectFormProps { onSave: (name: string, topic: string) => Promise; onCancel: () => void; } function NewProjectForm({ onSave, onCancel }: NewProjectFormProps) { const [name, setName] = useState(''); const [topic, setTopic] = useState(''); const [saving, setSaving] = useState(false); const [error, setError] = useState(''); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!name.trim()) { setError('Project name is required'); return; } if (!topic.trim()) { setError('Discussion topic is required'); return; } setSaving(true); setError(''); try { await onSave(name.trim(), topic.trim()); } catch (err) { setError(`Save failed: ${(err as Error).message}`); setSaving(false); } }; return (

{t('projects.newProject')}

setName(e.target.value)} placeholder="API Design Review" className="input-base w-full" autoFocus />