Skip to content

Commit

Permalink
Merge pull request #95 from JangGusWjd/dev/chat-ui
Browse files Browse the repository at this point in the history
[FE-DEV, UPDATE] 채팅 ui 구현, 멘토링 신청, 조회 api 연결
  • Loading branch information
JangGusWjd authored Aug 1, 2024
2 parents 249be8b + 3abb8ac commit bea655e
Show file tree
Hide file tree
Showing 9 changed files with 521 additions and 33 deletions.
Binary file added src/assets/img/gif.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
125 changes: 125 additions & 0 deletions src/components/mentoring/MenteeChat.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { ReactComponent as SendIcon } from "../../assets/icon/send.svg";
import Gif from "../../assets/img/gif.gif";
import "../../styles/mentoring/MenteeChat.scss";
import { useState } from "react";
import axios from "axios";

interface ChatMessage {
sender: "me" | "gpt";
text: string;
time: string;
}

const MenteeChat = () => {
const [message, setMessage] = useState<string>("");
const [chatMessages, setChatMessages] = useState<ChatMessage[]>([]);

const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setMessage(e.target.value);
};

const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (message.trim() !== "") {
const currentTime = new Date().toLocaleTimeString("ko-KR", {
hour: "2-digit",
minute: "2-digit",
hour12: true,
});

setChatMessages((prevMessages) => [
...prevMessages,
{ sender: "me", text: message, time: currentTime },
]);
const userMessage = message;
setMessage("");

try {
const storedAuth = localStorage.getItem("auth");
const auth = storedAuth ? JSON.parse(storedAuth) : null;
const accessToken = auth ? auth.access_token : null;
const response = await axios.post(
"http://3.35.123.253/api/mentorings/chat_with_gpt/",
{ message: userMessage },
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
}
);

if (response.status === 200) {
const replyTime = new Date().toLocaleTimeString("ko-KR", {
hour: "2-digit",
minute: "2-digit",
hour12: true,
});

setChatMessages((prevMessages) => [
...prevMessages,
{
sender: "gpt",
text: response.data.chat_response,
time: replyTime,
},
]);
} else {
console.error("Server error:", response.statusText);
}
} catch (error) {
console.error("Error sending message:", error);
}
}
};

return (
<div className="chatting-container">
<div className="chat-window">
<div className="chat-message">
{chatMessages.length === 0 ? (
<div className="no-messages">
<img src={Gif} alt="" />
<h2>챗봇과 대화를 통해 나에게 필요한 멘토링을 추천받으세요.</h2>
<h2>먼저 메시지를 보내면 챗봇과 대화가 시작됩니다.</h2>
</div>
) : (
chatMessages.map((msg, index) => (
<div
key={index}
className={`${
msg.sender === "me" ? "my-message" : "gpt-message"
}`}
>
{msg.sender === "me" ? (
<>
<span className="message-time">{msg.time}</span>
<p>{msg.text}</p>
</>
) : (
<>
<p>{msg.text}</p>
<span className="message-time">{msg.time}</span>
</>
)}
</div>
))
)}
</div>
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="메시지를 입력해주세요."
value={message}
onChange={handleInputChange}
/>
<SendIcon stroke="#1b1c3a" type="submit" />
</form>
</div>
<div className="chat-list">
<h1>💬 채팅 목록</h1>
</div>
</div>
);
};

export default MenteeChat;
13 changes: 13 additions & 0 deletions src/components/mentoring/MenteeCheck.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const MenteeCheck = () => {
return (
<div>
<div>
<h1>멘토링 제목</h1>
<p>멘토링 내용</p>
<button>확정</button>
</div>
</div>
);
};

export default MenteeCheck;
36 changes: 28 additions & 8 deletions src/components/mentoring/MentorAll.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { useState } from "react";
import { useState, useEffect } from "react";
import { ReactComponent as CloseIcon } from "../../assets/icon/close.svg";
import { ReactComponent as StarIcon } from "../../assets/icon/review-star.svg";
import "../../styles/mentoring/MentorAll.scss";
import { fetchNoMajorTokenData } from "../../api/fetchData";
import { MentoringData } from "../../types/Types";

const data = [
{
Expand Down Expand Up @@ -43,10 +45,25 @@ const data = [
];

const MentorAll = () => {
const [mentoringData, setMentoringData] = useState<MentoringData[]>([]);
const [isModalOpen, setIsModalOpen] = useState(false);
const [recommendation, setRecommendation] = useState("");
const [rating, setRating] = useState(0);

const fetchUserData = async () => {
const storedAuth = localStorage.getItem("auth");
const auth = storedAuth ? JSON.parse(storedAuth) : null;
const userId = auth ? auth.user_id : null;
const data = await fetchNoMajorTokenData(`/profile/mentorings/${userId}/`);
if (data) {
setMentoringData(data);
}
};

useEffect(() => {
fetchUserData();
}, []);

const openModal = () => {
setIsModalOpen(true);
};
Expand All @@ -68,19 +85,22 @@ const MentorAll = () => {
<div className="mentor">
<h1>"멘토"로 참여중인 프로그램</h1>
<div className="container">
{data.map((item, index) => (
{mentoringData.map((item, index) => (
<div className="mentoring-content" key={index}>
<div className="img-box">
<img src={item.img} alt="user" />
<img
src={
"https://watermark.lovepik.com/photo/20211202/large/lovepik-foreign-teacher-smiles-and-writes-a-blackboard-picture_501383572.jpg"
}
alt="user"
/>
</div>
<div className="content-box">
<div>
<h1>👩🏻‍🏫&nbsp;{item.name}</h1>
<h1>👩🏻‍🏫&nbsp;{item.user_name}</h1>
<h2>{item.title}</h2>
<p>{item.content}</p>
<span>
신청인원 | {item.apply_count} / {item.max}
</span>
<p>{item.description}</p>
<span>신청인원 | / {item.mentee_num}</span>
</div>
<div className="button">
<button>확정</button>
Expand Down
5 changes: 4 additions & 1 deletion src/components/mentoring/MentorMain.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ const MentorMain = () => {
const goMentorWrite = () => {
navigate("/main/mentoring/mentor");
};
const goMenteeChat = () => {
navigate("/main/mentoring/chat");
};
return (
<div className="mentor-main-container">
<div className="mentor-main-top">
Expand Down Expand Up @@ -40,7 +43,7 @@ const MentorMain = () => {
학습, 대인관계, 학교생활, 취업상담 등 도움이 필요한 분야의 멘토링을
신청하세요.
</p>
<button>나에게 맞는 멘토링 신청하기</button>
<button onClick={goMenteeChat}>나에게 맞는 멘토링 신청하기</button>
</div>
</div>
</div>
Expand Down
Loading

0 comments on commit bea655e

Please sign in to comment.