"use client"; import * as React from "react"; export interface Message { id: string; content: string; sender: "user" | "ai"; timestamp: Date; type?: "text" | "error" | "system"; isStreaming?: boolean; } interface ChatDockProps { isOpen: boolean; onClose: () => void; onMinimize?: () => void; onSendMessage: (message: string) => void; messages: Message[]; isTyping?: boolean; title?: string; placeholder?: string; className?: string; maxHeight?: string; position?: "bottom-right" | "bottom-left" | "center"; showHeader?: boolean; allowMinimize?: boolean; disabled?: boolean; } export function ChatDock({ isOpen, onClose, onMinimize, onSendMessage, messages, isTyping = false, title = "Chat", placeholder = "Type your message...", className = "", maxHeight = "600px", position = "bottom-right", showHeader = true, allowMinimize = true, disabled = false, }: ChatDockProps) { const [inputValue, setInputValue] = React.useState(""); const [isMinimized, setIsMinimized] = React.useState(false); const messagesEndRef = React.useRef(null); const inputRef = React.useRef(null); // Auto-scroll to bottom when new messages arrive React.useEffect(() => { if (messagesEndRef.current && !isMinimized) { messagesEndRef.current.scrollIntoView({ behavior: "smooth" }); } }, [messages, isMinimized]); // Focus input when dock opens React.useEffect(() => { if (isOpen && !isMinimized && inputRef.current) { const timer = setTimeout(() => { inputRef.current?.focus(); }, 100); return () => clearTimeout(timer); } }, [isOpen, isMinimized]); const handleSendMessage = React.useCallback(() => { const trimmedValue = inputValue.trim(); if (trimmedValue && !disabled) { onSendMessage(trimmedValue); setInputValue(""); } }, [inputValue, onSendMessage, disabled]); const handleKeyPress = React.useCallback( (event: React.KeyboardEvent) => { if (event.key === "Enter" && !event.shiftKey) { event.preventDefault(); handleSendMessage(); } }, [handleSendMessage] ); const handleMinimize = React.useCallback(() => { setIsMinimized(!isMinimized); if (onMinimize) { onMinimize(); } }, [isMinimized, onMinimize]); const getPositionClasses = () => { switch (position) { case "bottom-left": return "bottom-24 left-6"; case "center": return "top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"; default: return "bottom-24 right-6"; } }; const formatTimestamp = (timestamp: Date) => { return timestamp.toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit", }); }; if (!isOpen) return null; return (
{/* Header */} {showHeader && (

{title}

{allowMinimize && ( )}
)} {/* Messages Container */} {!isMinimized && ( <>
{messages.map((message) => { const isUser = message.sender === "user"; const isError = message.type === "error"; const isSystem = message.type === "system"; return (
{message.content}
{formatTimestamp(message.timestamp)}
); })} {/* Typing Indicator */} {isTyping && (
Typing...
)}
{/* Input Area */}
setInputValue(e.target.value)} onKeyPress={handleKeyPress} placeholder={placeholder} disabled={disabled} className="flex-1 px-4 py-2 border border-gray-300 rounded-full focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:opacity-50 disabled:cursor-not-allowed" maxLength={1000} />
)}
); } export default ChatDock;