"use client"; import React, { useState, useRef, useEffect, useCallback } from "react"; import { Button } from "@/components/ui/Button"; import SuggestedQuestions from "./suggested-questions"; import { useI18n, RTLText } from "./i18n-context"; 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; showSuggestedQuestions?: boolean; suggestedQuestionsContext?: string; } export function ChatDock({ isOpen, onClose, onMinimize, onSendMessage, messages, isTyping = false, title, placeholder, className = "", maxHeight = "600px", position = "bottom-right", showHeader = true, allowMinimize = true, disabled = false, showSuggestedQuestions = true, suggestedQuestionsContext = "welcome", }: ChatDockProps) { // Use i18n context const { t, isRTL, currentLanguage } = useI18n(); // Use default values from translations if not provided const displayTitle = title || t("chatbot"); const displayPlaceholder = placeholder || t("placeholder"); const [inputValue, setInputValue] = useState(""); const [isMinimized, setIsMinimized] = useState(false); const messagesEndRef = useRef(null); const inputRef = useRef(null); const messagesContainerRef = useRef(null); // Auto-scroll to bottom when new messages arrive useEffect(() => { if (messagesEndRef.current && !isMinimized) { messagesEndRef.current.scrollIntoView({ behavior: "smooth" }); } }, [messages, isMinimized]); // Focus input when dock opens useEffect(() => { if (isOpen && !isMinimized && inputRef.current) { const timer = setTimeout(() => { inputRef.current?.focus(); }, 100); return () => clearTimeout(timer); } }, [isOpen, isMinimized]); const handleSendMessage = useCallback(() => { const trimmedValue = inputValue.trim(); if (trimmedValue && !disabled) { onSendMessage(trimmedValue); setInputValue(""); } }, [inputValue, onSendMessage, disabled]); const handleKeyPress = useCallback( (event: React.KeyboardEvent) => { if (event.key === "Enter" && !event.shiftKey) { event.preventDefault(); handleSendMessage(); } }, [handleSendMessage] ); const handleMinimize = 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("ko-KR", { hour: "2-digit", minute: "2-digit", }); }; const TypingIndicator = () => (
{t("typing")}
); const MessageBubble = ({ message }: { message: Message }) => { const isUser = message.sender === "user"; const isError = message.type === "error"; const isSystem = message.type === "system"; return (
{message.content}
{formatTimestamp(message.timestamp)}
); }; if (!isOpen) return null; return (
{/* Header */} {showHeader && (

{displayTitle}

{allowMinimize && ( )}
)} {/* Messages Container */} {!isMinimized && (
{messages.length === 0 ? (
💬
{t("welcomeMessage")} {/* Suggested Questions for first-time users */} {showSuggestedQuestions && (
)}
) : ( messages.map((message) => ( )) )} {isTyping && }
)} {/* Input Area */} {!isMinimized && (
setInputValue(e.target.value)} onKeyDown={handleKeyPress} placeholder={displayPlaceholder} disabled={disabled || isTyping} className="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500" aria-label={t("sendMessage")} dir={isRTL ? "rtl" : "ltr"} />
{currentLanguage === "ko" ? "Enter로 전송 • Shift+Enter로 줄바꿈" : currentLanguage === "ja" ? "Enterで送信 • Shift+Enterで改行" : currentLanguage === "ar" ? "اضغط Enter للإرسال • Shift+Enter للسطر الجديد" : "Press Enter to send • Shift+Enter for new line"}
)}
); } export default ChatDock;