Spaces:
Build error
Build error
File size: 3,487 Bytes
6a059d3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | "use client"
import { useEffect, useRef } from "react"
import { cn } from "@/lib/utils"
import { User, Bot } from "lucide-react"
export interface TranscriptMessage {
id: string
role: "user" | "agent"
content: string
timestamp: Date
isStreaming?: boolean
}
interface TranscriptDisplayProps {
messages: TranscriptMessage[]
className?: string
}
export function TranscriptDisplay({ messages, className }: TranscriptDisplayProps) {
const scrollRef = useRef<HTMLDivElement>(null)
useEffect(() => {
// Auto-scroll to bottom when new messages arrive
if (scrollRef.current) {
scrollRef.current.scrollTop = scrollRef.current.scrollHeight
}
}, [messages])
const formatTime = (date: Date) => {
return new Intl.DateTimeFormat("en-US", {
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
}).format(date)
}
return (
<div
ref={scrollRef}
className={cn(
"flex flex-col gap-4 h-full overflow-y-auto p-4",
"scrollbar-thin scrollbar-thumb-border scrollbar-track-transparent",
className
)}
>
{messages.length === 0 ? (
<div className="flex items-center justify-center h-full text-muted-foreground text-sm">
<div className="text-center">
<p>Start speaking to see the conversation transcript</p>
<p className="text-xs mt-2">Your words will appear here in real-time</p>
</div>
</div>
) : (
messages.map((message) => (
<div
key={message.id}
className={cn(
"flex gap-3 animate-in fade-in slide-in-from-bottom-2",
message.role === "user" ? "justify-end" : "justify-start"
)}
>
{message.role === "agent" && (
<div className="flex-shrink-0 w-8 h-8 rounded-full bg-primary/10 flex items-center justify-center">
<Bot className="w-4 h-4 text-primary" />
</div>
)}
<div
className={cn(
"max-w-[80%] rounded-2xl px-4 py-3 shadow-sm",
message.role === "user"
? "bg-primary text-primary-foreground"
: "bg-muted text-muted-foreground"
)}
>
<div className="flex items-start gap-2">
<div className="flex-1">
<p className="text-sm leading-relaxed whitespace-pre-wrap break-words">
{message.content}
{message.isStreaming && (
<span className="inline-block w-2 h-4 ml-1 bg-current animate-pulse" />
)}
</p>
</div>
</div>
<div
className={cn(
"text-xs mt-2 opacity-70",
message.role === "user" ? "text-primary-foreground/70" : "text-muted-foreground/70"
)}
>
{formatTime(message.timestamp)}
</div>
</div>
{message.role === "user" && (
<div className="flex-shrink-0 w-8 h-8 rounded-full bg-primary/10 flex items-center justify-center">
<User className="w-4 h-4 text-primary" />
</div>
)}
</div>
))
)}
</div>
)
}
|