Skip to content

Commit 7ae4678

Browse files
committed
Merge branch 'dev' of https://github.com/MBTips/FE-MBTips into feat/일반-콘텐츠-header-문구-변경
2 parents e8249a4 + 94e28f5 commit 7ae4678

File tree

1 file changed

+68
-44
lines changed

1 file changed

+68
-44
lines changed

src/pages/Chat.tsx

Lines changed: 68 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { useEffect, useRef, useState, ChangeEvent, KeyboardEvent } from "react";
2+
import { useLocation } from "react-router-dom";
23
import IntroGuide from "@/components/IntroGuide";
34
import Header from "@/components/header/Header";
45
import ChatMessage from "@/components/ChatMessage";
56
import ChatActionBar from "@/components/ChatActionBar";
6-
import pickMbtiImage from "@/utils/pickMbtiImage";
7-
import instance from "@/api/axios";
8-
import { useLocation } from "react-router-dom";
97
import TipsMenuContainer from "@/components/tips/TipsMenuContainer";
8+
import pickMbtiImage from "@/utils/pickMbtiImage";
9+
import { authInstance } from "@/api/axios";
1010
import { trackEvent } from "@/libs/analytics";
1111

1212
interface Message {
@@ -18,81 +18,107 @@ interface ChatResponse {
1818
data: string;
1919
}
2020

21+
interface GetChatHistoryAPIResponse {
22+
data: ChatHistoryResponse[];
23+
}
24+
25+
interface ChatHistoryResponse {
26+
messageContent: string;
27+
virtualFriendId: number | null;
28+
}
29+
2130
const Chat = () => {
2231
const { state } = useLocation();
2332
const { mbti, mode, id = Date.now().toString(), name } = state;
2433

2534
const [messages, setMessages] = useState<Message[]>([]);
2635
const [input, setInput] = useState("");
2736
const [isOpen, setIsOpen] = useState(false);
28-
const bottomRef = useRef<HTMLDivElement | null>(null);
37+
const bottomRef = useRef<HTMLDivElement>(null);
2938

3039
const chatTitle = mode === "fastFriend" ? `${mbti}와 대화` : `${name}과 대화`;
31-
const assistantInfo = mbti;
32-
const assistantImgUrl = pickMbtiImage(assistantInfo);
40+
const assistantImgUrl = pickMbtiImage(mbti);
3341
const storageKey = `chatMessages_${id}`;
3442

3543
useEffect(() => {
36-
bottomRef.current?.scrollIntoView({ behavior: "smooth" });
37-
}, [messages, isOpen]);
44+
const fetchMessages = async () => {
45+
if (mode === "virtualFriend") {
46+
try {
47+
const virtualFriendChatHistory =
48+
await authInstance.get<GetChatHistoryAPIResponse>(
49+
`/api/message/${id}`
50+
);
51+
const chatHistory = virtualFriendChatHistory.data.data;
52+
53+
const fetchedMessages: Message[] = chatHistory.map((msg) => ({
54+
role: msg.virtualFriendId ? "assistant" : "user",
55+
content: msg.messageContent
56+
}));
57+
58+
setMessages(fetchedMessages);
59+
} catch (error) {
60+
console.error("채팅 불러오기 실패", error);
61+
}
62+
} else {
63+
const storedMessage = sessionStorage.getItem(storageKey);
64+
if (storedMessage) {
65+
setMessages(JSON.parse(storedMessage));
66+
}
67+
}
68+
};
69+
70+
fetchMessages();
71+
}, [mode, id, storageKey]);
3872

3973
useEffect(() => {
40-
const stored = sessionStorage.getItem(storageKey);
41-
if (stored) setMessages(JSON.parse(stored));
42-
}, [storageKey]);
74+
if (mode !== "virtualFriend") {
75+
sessionStorage.setItem(storageKey, JSON.stringify(messages));
76+
}
77+
}, [messages, mode, storageKey]);
4378

4479
useEffect(() => {
45-
sessionStorage.setItem(storageKey, JSON.stringify(messages));
46-
}, [messages, storageKey]);
80+
bottomRef.current?.scrollIntoView({ behavior: "smooth" });
81+
}, [messages, isOpen]);
4782

4883
const handleToggleTips = () => {
49-
const nextAction = !isOpen;
50-
84+
const nextState = !isOpen;
5185
trackEvent("Click", {
5286
page: "채팅방",
53-
element: nextAction ? "콘텐츠 열기" : "콘텐츠 닫기"
87+
element: nextState ? "콘텐츠 열기" : "콘텐츠 닫기"
5488
});
55-
56-
setIsOpen(nextAction);
89+
setIsOpen(nextState);
5790
};
5891

5992
const handleSend = async (messageToSend: string) => {
6093
if (!messageToSend.trim()) return;
6194

62-
const newMessages: Message[] = [
95+
const updatedMessages: Message[] = [
6396
...messages,
6497
{ role: "user", content: messageToSend }
6598
];
66-
setMessages(newMessages);
99+
setMessages(updatedMessages);
67100
setInput("");
68101

69102
try {
70-
let url = "";
71-
let payload = {};
72-
73-
if (mode === "fastFriend") {
74-
url = "/api/fast-friend/message";
75-
payload = { fastFriendId: id, content: messageToSend };
76-
} else {
77-
url = "/api/message";
78-
payload = {
79-
conversationId: id,
80-
messageContent: messageToSend
81-
};
82-
}
103+
const url =
104+
mode === "fastFriend" ? "/api/fast-friend/message" : "/api/message";
105+
const payload =
106+
mode === "fastFriend"
107+
? { fastFriendId: id, content: messageToSend }
108+
: { conversationId: id, messageContent: messageToSend };
83109

84-
const response = await instance.post<ChatResponse>(url, payload);
110+
const { data } = await authInstance.post<ChatResponse>(url, payload);
85111

86112
setMessages([
87-
...newMessages,
113+
...updatedMessages,
88114
{
89115
role: "assistant",
90-
content: response.data.data || "응답이 없어요"
116+
content: data.data || "응답이 없어요"
91117
}
92118
]);
93-
} catch (e) {
119+
} catch (error) {
94120
setMessages([
95-
...newMessages,
121+
...updatedMessages,
96122
{ role: "assistant", content: "오류가 발생했어요. 다시 시도해 주세요." }
97123
]);
98124
}
@@ -104,7 +130,7 @@ const Chat = () => {
104130

105131
const handleKeyup = (e: KeyboardEvent<HTMLInputElement>) => {
106132
if (e.key === "Enter") {
107-
handleSend(e.currentTarget.value);
133+
handleSend(input);
108134
}
109135
};
110136

@@ -115,12 +141,10 @@ const Chat = () => {
115141
<div className="flex-1 space-y-4 overflow-y-auto px-[20px] pt-6">
116142
<IntroGuide />
117143
{/* 메시지 리스트 */}
118-
{messages.map((msg, index) => (
144+
{messages.map((msg, idx) => (
119145
<div
120-
key={index}
121-
className={`flex ${
122-
msg.role === "user" ? "justify-end" : "justify-start"
123-
} items-start`}
146+
key={idx}
147+
className={`flex ${msg.role === "user" ? "justify-end" : "justify-start"} items-start`}
124148
>
125149
{/* 캐릭터 아이콘 */}
126150
{msg.role === "assistant" && (

0 commit comments

Comments
 (0)