From 6a7fe94b93c05370ab744cb8f33ddfbd4efa9be4 Mon Sep 17 00:00:00 2001 From: FanisNgv Date: Wed, 11 Sep 2024 15:14:31 +0300 Subject: [PATCH] conversations[id] --- frontend/src/app/conversations/[id]/page.tsx | 285 +++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 frontend/src/app/conversations/[id]/page.tsx diff --git a/frontend/src/app/conversations/[id]/page.tsx b/frontend/src/app/conversations/[id]/page.tsx new file mode 100644 index 0000000..6712d0f --- /dev/null +++ b/frontend/src/app/conversations/[id]/page.tsx @@ -0,0 +1,285 @@ +"use client"; + +import { useState, useEffect } from 'react'; +import { api } from '@/domain/api/api'; +import Sidebar from '../../components/Sidebar'; +import MessageList from '../../components/MessageList'; +import { useConfig } from '@/domain/config/ConfigProvider'; +import { Button } from "@/components/ui/button" +import { useRouter } from 'next/navigation'; + +// Тип для хранения информации о чате +type Conversation = { + id: number; + name: string; + messages: Array<{ id: number; text: string; sender: string }>; +}; + +// Основная функция компонента +export default function ConversationPage({ params }: { params: { id: string } }) { + // Состояния для хранения списка чатов, текущего чата и сообщений + const [conversations, setConversations] = useState([]); + const [currentConversationId, setCurrentConversationId] = useState(null); + const [message, setMessage] = useState(''); + const [messages, setMessages] = useState>([]); + const [isSidebarOpen, setIsSidebarOpen] = useState(false); + + const config = useConfig(); + const router = useRouter(); + + // Инициализация пользователя + useEffect(() => { + const initializeUser = async () => { + try { + const response = await api.get_messages__user_id_(config.ENDPOINT); + console.log('API response:', response); + + if (response.data && Array.isArray(response.data) && response.data.length > 0) { + const formattedConversations = response.data.map((id: number, index: number) => ({ + id: id, + name: `Чат ${index + 1}`, + messages: [] + })); + + setConversations(formattedConversations); + + const initialConversationId = parseInt(params.id); + setCurrentConversationId(initialConversationId); + + await loadMessagesForConversation(initialConversationId); + } else { + const newConversation = await handleAddConversation(); + setConversations([newConversation]); + setCurrentConversationId(newConversation.id); + router.push(`/conversations/${newConversation.id}`); + } + } catch (error) { + console.error('Ошибка при инициализации пользователя:', error); + } + }; + + initializeUser(); + }, [params.id, config.ENDPOINT, router]); + + useEffect(() => { + const loadData = async () => { + if (currentConversationId) { + await loadMessagesForConversation(currentConversationId); + } + }; + + loadData(); + }, [currentConversationId, config.ENDPOINT]); + + const handleSendMessage = async () => { + if (!message.trim()) return; + + try { + if (currentConversationId === null) { + const newConversation = await handleAddConversation(); + if (!newConversation) { + throw new Error('Не удалось создать новый чат'); + } + } + const newMessage = { + id: messages.length + 1, + text: message, + sender: 'user' + }; + + const conversationIdAtSend = currentConversationId; + + setMessages(prevMessages => [...prevMessages, newMessage]); + setConversations(prevConversations => + prevConversations.map(conversation => + conversation.id === conversationIdAtSend + ? { ...conversation, messages: [...conversation.messages, newMessage] } + : conversation + ) + ); + + const response = await api.sendMessage(config.ENDPOINT, conversationIdAtSend!, message); + + if (!response.task_id) { + throw new Error('Ошибка при отправке сообщения'); + } + + console.log('Сообщение успешно отправлено, task_id:', response.task_id); + setMessage(''); + + let botResponse; + do { + await new Promise(resolve => setTimeout(resolve, 1000)); + botResponse = await api.checkTaskResult(config.ENDPOINT, response.task_id); + } while (!botResponse.ready); + + if (botResponse.successful && botResponse.value) { + const botMessage = { + id: messages.length + 2, + text: botResponse.value.answer, + sender: 'bot' + }; + + setMessages(prevMessages => [...prevMessages, botMessage]); + setConversations(prevConversations => + prevConversations.map(conversation => + conversation.id === currentConversationId + ? { ...conversation, messages: [...conversation.messages, botMessage] } + : conversation + ) + ); + } + + } catch (error) { + console.error('Произошла ошибка:', error); + setMessage(''); + } + }; + + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter') { + handleSendMessage(); + } + }; + + const handleChatChange = async (id: number) => { + setCurrentConversationId(id); + await loadMessagesForConversation(id); + router.push(`/conversations/${id}`); + }; + + const handleAddConversation = async () => { + try { + const response = await api.createConversation(config.ENDPOINT); + if (response.conversation_id) { + const maxChatNumber = Math.max(...conversations.map(conv => { + const match = conv.name.match(/Чат (\d+)/); + return match ? parseInt(match[1]) : 0; + }), 0); + + const newChatNumber = maxChatNumber + 1; + + const newConversation = { + id: response.conversation_id, + name: `Чат ${newChatNumber}`, + messages: [] + }; + + setConversations(prevConversations => [...prevConversations, newConversation]); + setCurrentConversationId(newConversation.id); + setMessages([]); + return newConversation; + } else { + throw new Error('Не удалось создать новый чат'); + } + } catch (error) { + console.error('Ошибка при создании чата:', error); + throw error; + } + }; + + const handleDeleteConversation = async (conversationId: number) => { + try { + await api.deleteConversation(config.ENDPOINT, conversationId); + + setConversations(prevConversations => { + const updatedConversations = prevConversations.filter(conversation => conversation.id !== conversationId); + if (updatedConversations.length === 0) { + setCurrentConversationId(null); + setMessages([]); + } else if (currentConversationId === conversationId) { + const newCurrentConversation = updatedConversations[0]; + setCurrentConversationId(newCurrentConversation.id); + setMessages(newCurrentConversation.messages); + } + return updatedConversations; + }); + console.log('Чат успешно удален'); + } catch (error) { + console.error('Ошибка при удалении чата:', error); + } + }; + + const loadMessagesForConversation = async (conversationId: number) => { + try { + const response = await api.getMessages(config.ENDPOINT, conversationId); + if (response && response.length > 0 && response[0].messages && response[0].messages.length > 0) { + const conversationMessages = response[0].messages[0][conversationId]; + if (conversationMessages && Array.isArray(conversationMessages)) { + const formattedMessages = conversationMessages.map((msg: any) => ({ + id: msg.id, + text: msg.text, + sender: msg.role === 1 ? 'bot' : 'user' + })); + setMessages(formattedMessages); + setConversations(prevConversations => + prevConversations.map(conv => + conv.id === conversationId ? { ...conv, messages: formattedMessages } : conv + ) + ); + } else { + setMessages([]); + } + } else { + setMessages([]); + } + } catch (error) { + console.error('Ошибка при загрузке сообщений:', error); + } + }; + + return ( +
+
+ {isSidebarOpen && ( + + )} +
+ +
+
+ handleDeleteConversation(id)} + isSidebarOpen={isSidebarOpen} + onCloseSidebar={() => setIsSidebarOpen(false)} + /> +
+ +
+ + +
+
+ setMessage(e.target.value)} + onKeyDown={handleKeyDown} + placeholder="Введите ваш вопрос" + className="flex-grow p-2 bg-[#EFF0F3] border border-gray-300 rounded-l-2xl focus:outline-none h-full" + style={{ color: 'black' }} + /> + +
+
+
+
+
+ ); +}