"use client"; import { useEffect, useRef, useState } from "react"; import { Chat, ChatMessage, getProjectChat, getChatMessages, } from "@/lib/api"; import { wsClient } from "@/lib/ws"; interface ChatPanelProps { projectId: string; } export default function ChatPanel({ projectId }: ChatPanelProps) { const [chat, setChat] = useState(null); const [messages, setMessages] = useState([]); const [input, setInput] = useState(""); const [expanded, setExpanded] = useState(false); const [collapsed, setCollapsed] = useState(false); const messagesEndRef = useRef(null); const inputRef = useRef(null); // Load chat and messages useEffect(() => { let cancelled = false; getProjectChat(projectId).then((c) => { if (cancelled) return; setChat(c); getChatMessages(c.id).then((msgs) => { if (!cancelled) setMessages(msgs); }); }); return () => { cancelled = true; }; }, [projectId]); // WebSocket: subscribe to chat room useEffect(() => { if (!chat) return; wsClient.connect(); wsClient.subscribeChat(chat.id); const unsub = wsClient.on("chat.message", (msg: any) => { if (msg.chat_id === chat.id) { setMessages((prev) => [ ...prev, { id: msg.id, chat_id: msg.chat_id, sender_type: msg.sender_type, sender_id: msg.sender_id, sender_name: msg.sender_name, content: msg.content, created_at: msg.created_at, }, ]); } }); return () => { wsClient.unsubscribeChat(chat.id); unsub(); }; }, [chat]); // Auto-scroll useEffect(() => { messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); }, [messages]); const handleSend = () => { if (!chat || !input.trim()) return; const text = input.trim(); setInput(""); // Send via WebSocket — message will come back via chat.message event wsClient.send("chat.send", { chat_id: chat.id, content: text, sender_type: "human", sender_name: "admin", }); inputRef.current?.focus(); }; const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); handleSend(); } }; if (collapsed) { return (
); } const panelHeight = expanded ? "h-full" : "h-[30vh]"; return (
{/* Header */}
💬 Чат проекта
{/* Messages */}
{messages.length === 0 && (

Пока пусто. Напишите первое сообщение 💬

)} {messages.map((msg) => (
{msg.sender_name || msg.sender_type}: {msg.content} {new Date(msg.created_at).toLocaleTimeString("ru-RU", { hour: "2-digit", minute: "2-digit" })}
))}
{/* Input */}
setInput(e.target.value)} onKeyDown={handleKeyDown} placeholder="Написать сообщение..." className="flex-1 bg-[var(--bg)] border border-[var(--border)] rounded px-3 py-1.5 text-sm outline-none focus:border-[var(--accent)]" disabled={!chat} />
); }