- TypeScript types for chat session, messages, and responses - API client module with all 6 endpoints - Zustand store with session management, message sending, tree generation, import, resume - 7 chat components: ChatMessage, ChatInput, ChatPanel, PhaseIndicator, ChatToolbar, EmptyPreview, StaticTreePreview - AIChatBuilderPage with split-panel layout (60% chat / 40% preview) - Route at /ai/chat with lazy loading - "Build with AI" button on TreeLibraryPage - Session resume via URL search params Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
42 lines
1.3 KiB
TypeScript
42 lines
1.3 KiB
TypeScript
import { Bot, User } from 'lucide-react'
|
|
import { MarkdownContent } from '@/components/ui/MarkdownContent'
|
|
import { cn } from '@/lib/utils'
|
|
import type { ChatMessage as ChatMessageType } from '@/types'
|
|
|
|
interface ChatMessageProps {
|
|
message: ChatMessageType
|
|
}
|
|
|
|
export function ChatMessage({ message }: ChatMessageProps) {
|
|
const isAI = message.role === 'assistant'
|
|
|
|
return (
|
|
<div className={cn('flex gap-3', isAI ? 'items-start' : 'items-start justify-end')}>
|
|
{isAI && (
|
|
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-primary/10">
|
|
<Bot className="h-4 w-4 text-primary" />
|
|
</div>
|
|
)}
|
|
<div
|
|
className={cn(
|
|
'max-w-[85%] rounded-xl px-4 py-3',
|
|
isAI
|
|
? 'bg-card border border-border'
|
|
: 'bg-primary/10 border border-primary/20'
|
|
)}
|
|
>
|
|
{isAI ? (
|
|
<MarkdownContent content={message.content} className="text-sm" />
|
|
) : (
|
|
<p className="text-sm text-foreground whitespace-pre-wrap">{message.content}</p>
|
|
)}
|
|
</div>
|
|
{!isAI && (
|
|
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-accent">
|
|
<User className="h-4 w-4 text-foreground" />
|
|
</div>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|