Files
resolutionflow/frontend/src/components/script-builder/ScriptBuilderChat.tsx
chihlasm ff985fb755 refactor: replace cyan accent with ember orange across entire frontend
Swap accent color from cyan (#22d3ee) to ember orange (#f97316) site-wide.
Cyan caused contrast issues and felt generic — orange brings warmth and
urgency fitting for a troubleshooting tool.

Changes:
- CSS variables: accent, accent-hover, accent-dim, accent-text, primary, ring
- Warning color shifted from amber (#fbbf24) to yellow (#eab308) for
  semantic separation from orange accent
- Brand SVGs: logo gradient updated to orange
- 50+ component files: all hardcoded cyan hex values, Tailwind cyan-*
  classes, and rgba(34,211,238,...) glow values replaced
- landing.css: all 45+ cyan references + 5 old border color fixes
- DESIGN-SYSTEM.md bumped to v5 with decisions log
- CLAUDE.md: all color references synced to charcoal palette + orange accent
- PWA theme-color meta tag updated to match sidebar (#10121a)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 07:37:44 +00:00

115 lines
3.9 KiB
TypeScript

import { useEffect, useRef } from 'react'
import { Bot, User, Loader2 } from 'lucide-react'
import { cn } from '@/lib/utils'
import { MarkdownContent } from '@/components/ui/MarkdownContent'
import { ScriptCodeBlock } from './ScriptCodeBlock'
import type { ScriptBuilderMessage } from '@/types'
interface ScriptBuilderChatProps {
messages: ScriptBuilderMessage[]
language: string
onViewScript: (script: string, filename: string | null) => void
onSaveScript: () => void
isLoading: boolean
}
export function ScriptBuilderChat({
messages,
language,
onViewScript,
onSaveScript,
isLoading,
}: ScriptBuilderChatProps) {
const bottomRef = useRef<HTMLDivElement>(null)
useEffect(() => {
bottomRef.current?.scrollIntoView({ behavior: 'smooth' })
}, [messages.length, isLoading])
if (messages.length === 0 && !isLoading) {
return (
<div className="flex-1 flex items-center justify-center p-8">
<div className="text-center max-w-md">
<div className="w-14 h-14 rounded-2xl bg-primary flex items-center justify-center mx-auto mb-4">
<Bot size={28} className="text-white" />
</div>
<h2 className="text-lg font-heading font-bold text-foreground mb-2">
Script Builder
</h2>
<p className="text-sm text-muted-foreground leading-relaxed">
Describe the script you need and AI will generate it for you. You can iterate on the script,
preview it, and save it to your library.
</p>
</div>
</div>
)
}
return (
<div className="flex-1 overflow-y-auto p-4 space-y-4">
{messages.map((msg, idx) => (
<div
key={idx}
className={cn(
"flex gap-3",
msg.role === 'user' ? "justify-end" : "justify-start"
)}
>
{msg.role === 'assistant' && (
<div className="shrink-0 w-8 h-8 rounded-lg bg-[rgba(249,115,22,0.1)] flex items-center justify-center mt-0.5">
<Bot size={16} className="text-orange-400" />
</div>
)}
<div
className={cn(
"max-w-[85%] rounded-xl px-4 py-3 text-sm",
msg.role === 'user'
? "bg-[rgba(249,115,22,0.08)] border border-[rgba(249,115,22,0.15)] text-foreground"
: "card-flat"
)}
>
{msg.role === 'assistant' ? (
<>
<MarkdownContent content={msg.content} />
{msg.script && (
<ScriptCodeBlock
script={msg.script}
filename={msg.script_filename ?? null}
lineCount={msg.line_count ?? null}
language={language}
onViewFull={() => onViewScript(msg.script!, msg.script_filename ?? null)}
onSave={onSaveScript}
/>
)}
</>
) : (
<p className="whitespace-pre-wrap">{msg.content}</p>
)}
</div>
{msg.role === 'user' && (
<div className="shrink-0 w-8 h-8 rounded-lg bg-[rgba(255,255,255,0.06)] flex items-center justify-center mt-0.5">
<User size={16} className="text-muted-foreground" />
</div>
)}
</div>
))}
{isLoading && (
<div className="flex gap-3 justify-start">
<div className="shrink-0 w-8 h-8 rounded-lg bg-[rgba(249,115,22,0.1)] flex items-center justify-center">
<Bot size={16} className="text-orange-400" />
</div>
<div className="card-flat rounded-xl px-4 py-3 text-sm flex items-center gap-2">
<Loader2 size={14} className="animate-spin text-orange-400" />
<span className="text-muted-foreground">Generating script...</span>
</div>
</div>
)}
<div ref={bottomRef} />
</div>
)
}