- After generation, toolbar shows "Save to Flow Library" button (replaces "Import to Editor") - Button shows "Saving..." spinner state during API call - Generate button shows animated spinner during generation - Backend /import endpoint always creates a new Tree record (removed generated_tree_id idempotency check) - Navigates to tree editor after successful save Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
99 lines
2.9 KiB
TypeScript
99 lines
2.9 KiB
TypeScript
import { Sparkles, Save, RotateCcw, Loader2 } from 'lucide-react'
|
|
import { PhaseIndicator } from './PhaseIndicator'
|
|
import { cn } from '@/lib/utils'
|
|
import type { InterviewPhase } from '@/types'
|
|
|
|
interface ChatToolbarProps {
|
|
currentPhase: InterviewPhase
|
|
status: 'idle' | 'active' | 'completed' | 'abandoned'
|
|
isGenerating: boolean
|
|
hasGeneratedTree: boolean
|
|
isSaving: boolean
|
|
onGenerate: () => void
|
|
onSave: () => void
|
|
onReset: () => void
|
|
}
|
|
|
|
export function ChatToolbar({
|
|
currentPhase,
|
|
status,
|
|
isGenerating,
|
|
hasGeneratedTree,
|
|
isSaving,
|
|
onGenerate,
|
|
onSave,
|
|
onReset,
|
|
}: ChatToolbarProps) {
|
|
return (
|
|
<div className="flex items-center justify-between border-b border-border bg-card px-4 py-2">
|
|
<div className="flex items-center gap-3">
|
|
<div className="flex items-center gap-2 text-sm font-medium text-foreground">
|
|
<Sparkles className="h-4 w-4 text-primary" />
|
|
Flow Assist
|
|
</div>
|
|
<PhaseIndicator currentPhase={currentPhase} />
|
|
</div>
|
|
|
|
<div className="flex items-center gap-2">
|
|
{status === 'active' && !hasGeneratedTree && (
|
|
<button
|
|
onClick={onGenerate}
|
|
disabled={isGenerating}
|
|
className={cn(
|
|
'flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm font-medium',
|
|
'bg-gradient-brand text-white shadow-lg shadow-primary/20',
|
|
'hover:opacity-90 transition-opacity',
|
|
'disabled:opacity-50 disabled:cursor-not-allowed'
|
|
)}
|
|
>
|
|
{isGenerating ? (
|
|
<>
|
|
<Loader2 className="h-3.5 w-3.5 animate-spin" />
|
|
Generating...
|
|
</>
|
|
) : (
|
|
<>
|
|
<Sparkles className="h-3.5 w-3.5" />
|
|
Generate Flow
|
|
</>
|
|
)}
|
|
</button>
|
|
)}
|
|
|
|
{hasGeneratedTree && (
|
|
<button
|
|
onClick={onSave}
|
|
disabled={isSaving}
|
|
className={cn(
|
|
'flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm font-medium',
|
|
'bg-gradient-brand text-white shadow-lg shadow-primary/20',
|
|
'hover:opacity-90 transition-opacity',
|
|
'disabled:opacity-50 disabled:cursor-not-allowed'
|
|
)}
|
|
>
|
|
{isSaving ? (
|
|
<>
|
|
<Loader2 className="h-3.5 w-3.5 animate-spin" />
|
|
Saving...
|
|
</>
|
|
) : (
|
|
<>
|
|
<Save className="h-3.5 w-3.5" />
|
|
Save to Flow Library
|
|
</>
|
|
)}
|
|
</button>
|
|
)}
|
|
|
|
<button
|
|
onClick={onReset}
|
|
className="flex items-center gap-1.5 rounded-lg border border-border px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground transition-colors"
|
|
>
|
|
<RotateCcw className="h-3.5 w-3.5" />
|
|
Start Over
|
|
</button>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|