import { useState, useEffect } from 'react' import { X, CheckCircle2, ArrowUpRight, Pause, Loader2, Copy, Check, RefreshCw, ClipboardList, Sparkles, } from 'lucide-react' import { cn } from '@/lib/utils' import { MarkdownContent } from '@/components/ui/MarkdownContent' type ConclusionOutcome = 'resolved' | 'escalated' | 'paused' interface ConcludeSessionModalProps { isOpen: boolean onClose: () => void onConclude: (outcome: ConclusionOutcome, notes: string) => Promise onResumeNew: (summary: string) => void chatTitle: string } const OUTCOMES: { value: ConclusionOutcome; label: string; description: string; icon: typeof CheckCircle2; color: string; bg: string; border: string }[] = [ { value: 'resolved', label: 'Resolved', description: 'Issue has been fixed or answered', icon: CheckCircle2, color: 'text-emerald-400', bg: 'bg-emerald-400/10', border: 'border-emerald-400/30', }, { value: 'escalated', label: 'Escalate', description: 'Needs to be handed off or escalated', icon: ArrowUpRight, color: 'text-amber-400', bg: 'bg-amber-400/10', border: 'border-amber-400/30', }, { value: 'paused', label: 'Paused', description: 'Continuing later — saving progress', icon: Pause, color: 'text-blue-400', bg: 'bg-blue-400/10', border: 'border-blue-400/30', }, ] type ModalStep = 'select-outcome' | 'add-notes' | 'summary' export function ConcludeSessionModal({ isOpen, onClose, onConclude, onResumeNew, chatTitle, }: ConcludeSessionModalProps) { const [step, setStep] = useState('select-outcome') const [outcome, setOutcome] = useState(null) const [notes, setNotes] = useState('') const [summary, setSummary] = useState('') const [generating, setGenerating] = useState(false) const [copied, setCopied] = useState(false) const [error, setError] = useState(null) // Reset state when modal opens useEffect(() => { if (isOpen) { setStep('select-outcome') setOutcome(null) setNotes('') setSummary('') setGenerating(false) setCopied(false) setError(null) } }, [isOpen]) const handleOutcomeSelect = (selected: ConclusionOutcome) => { setOutcome(selected) setStep('add-notes') } const handleGenerate = async () => { if (!outcome) return setGenerating(true) setError(null) try { const result = await onConclude(outcome, notes) setSummary(result) setStep('summary') } catch { setError('Failed to generate summary. Please try again.') } finally { setGenerating(false) } } const handleCopy = async () => { try { await navigator.clipboard.writeText(summary) setCopied(true) setTimeout(() => setCopied(false), 2000) } catch { // Fallback const textarea = document.createElement('textarea') textarea.value = summary document.body.appendChild(textarea) textarea.select() document.execCommand('copy') document.body.removeChild(textarea) setCopied(true) setTimeout(() => setCopied(false), 2000) } } const handleResumeNew = () => { onResumeNew(summary) onClose() } if (!isOpen) return null const selectedOutcome = OUTCOMES.find(o => o.value === outcome) return (
{/* Backdrop */}
{/* Modal */}
{/* Header */}

Conclude Session

{chatTitle}

{/* Step indicator */}
{(['select-outcome', 'add-notes', 'summary'] as ModalStep[]).map((s, i) => (
{i > 0 && (
)}
{i + 1}
{s === 'select-outcome' ? 'Outcome' : s === 'add-notes' ? 'Notes' : 'Summary'}
))}
{/* Content */}
{/* Step 1: Select Outcome */} {step === 'select-outcome' && (

How did this session end?

{OUTCOMES.map(o => { const Icon = o.icon return ( ) })}
)} {/* Step 2: Add Notes */} {step === 'add-notes' && selectedOutcome && (
{/* Selected outcome badge */}
{selectedOutcome.label}