/** * CreateSessionWizard — 3-step wizard for creating a team meeting session. * * Step 1: Name & Description * Step 2: Select Personas (drag-style multi-select from available list) * Step 3: Settings (turn mode, agenda) * * Simple, easy-to-use flow modeled after the Agent project wizard. */ import React, { useState, useCallback } from 'react'; import { X, ChevronLeft, ChevronRight, Users, Settings, FileText, Check, Zap, MessageSquare, Crown, Activity, Workflow, DollarSign, } from 'lucide-react'; import { PersonaSelectorEnterprise } from './PersonaSelectorEnterprise'; import { TEAM_BUNDLES } from './teamBundles'; // --------------------------------------------------------------------------- // Helpers // --------------------------------------------------------------------------- const TURN_MODES = [ { value: 'reactive', label: 'Reactive (Recommended)', description: 'Only relevant personas speak — best for brainstorming and productivity', icon: , }, { value: 'round-robin', label: 'Round Robin', description: 'Each persona responds in order after you speak', icon: , }, { value: 'free-form', label: 'Free Form', description: 'Personas respond naturally as in a real conversation', icon: , }, { value: 'moderated', label: 'Moderated', description: 'You choose which persona speaks next', icon: , }, ]; const ENGINE_OPTIONS = [ { value: 'native', label: 'Conversation', description: 'Free-form discussion with smart speaker selection', icon: , }, { value: 'crew', label: 'Task Workflow', description: 'Stage-based collaboration with structured output', icon: , }, ]; const CREW_PROFILES = [ { id: 'task_planner_v1', label: 'Task Planner', description: 'Steps, details, review, and finalize' }, { id: 'brainstorm_v1', label: 'Brainstorm', description: 'Ideate, evaluate, and recommend' }, { id: 'draft_and_edit_v1', label: 'Draft & Edit', description: 'Outline, draft, and refine content' }, ]; // --------------------------------------------------------------------------- // Component // --------------------------------------------------------------------------- export function CreateSessionWizard({ personas, backendUrl, onCancel, onCreate, }) { const [step, setStep] = useState(1); const totalSteps = 3; // Step 1 const [name, setName] = useState(''); const [description, setDescription] = useState(''); // Step 2 const [selectedIds, setSelectedIds] = useState(new Set()); // Step 3 const [engine, setEngine] = useState('native'); const [crewProfileId, setCrewProfileId] = useState('task_planner_v1'); const [budgetLimit, setBudgetLimit] = useState(''); const [turnMode, setTurnMode] = useState('reactive'); const [agendaText, setAgendaText] = useState(''); const [creating, setCreating] = useState(false); const togglePersona = useCallback((id) => { setSelectedIds((prev) => { const next = new Set(prev); if (next.has(id)) next.delete(id); else next.add(id); return next; }); }, []); const canProceed = step === 1 ? name.trim().length > 0 : step === 2 ? selectedIds.size > 0 : true; const handleCreate = useCallback(async () => { if (creating) return; setCreating(true); try { const agenda = agendaText .split('\n') .map((l) => l.trim()) .filter(Boolean); const policy = engine === 'crew' ? { engine: 'crew', crew: { profile_id: crewProfileId, ...(budgetLimit ? { budget_limit_eur: parseFloat(budgetLimit) } : {}), }, } : { engine: 'native' }; await onCreate({ name: name.trim(), description: description.trim(), participant_ids: Array.from(selectedIds), turn_mode: turnMode, agenda, policy, }); } catch (e) { console.error('Failed to create session:', e); } finally { setCreating(false); } }, [creating, name, description, selectedIds, turnMode, agendaText, engine, crewProfileId, budgetLimit, onCreate]); return (
{/* ═══════════════ HEADER ═══════════════ */}
New Team Session
{/* ═══════════════ STEP INDICATOR ═══════════════ */}
{[ { n: 1, label: 'Details', icon: }, { n: 2, label: 'Personas', icon: }, { n: 3, label: 'Settings', icon: }, ].map(({ n, label, icon }) => ( {n > 1 &&
= n ? 'bg-cyan-500/40' : 'bg-white/[0.06]'}`}/>}
n ? 'bg-emerald-500/10 text-emerald-300 border border-emerald-500/20' : 'bg-white/[0.03] text-white/30 border border-white/[0.06]'}`}> {step > n ? : icon} {label}
))}
{/* ═══════════════ STEP CONTENT ═══════════════ */}
{/* Step 1: Details */} {step === 1 && (

Name your session

Give your meeting room a name and optional description.

setName(e.target.value)} placeholder="e.g., Morning Standup, Strategy Review..." className="w-full px-3.5 py-2.5 rounded-xl bg-white/[0.04] border border-white/[0.08] text-sm text-white placeholder:text-white/20 focus:outline-none focus:border-cyan-500/40 transition-colors" autoFocus/>