From a96da1814612654c6799edf5621e1394b3270077 Mon Sep 17 00:00:00 2001 From: HanJul_01 <129282275+Hanjuri@users.noreply.github.com> Date: Mon, 9 Sep 2024 13:59:00 +0900 Subject: [PATCH] =?UTF-8?q?feat:=EC=B1=84=ED=8C=85=EB=B0=A9=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Conflicts: # src/App.jsx # src/pages/chat/ChatRoom.jsx # vite.config.js --- .idea/inspectionProfiles/Project_Default.xml | 6 - src/api/ChatMessageCall.js | 2 +- src/api/JoinInfoPost.js | 14 ++ src/api/instanceAuth.js | 29 +++ src/components/Common/Header.jsx | 2 +- src/pages/Homepage/HomePage.jsx | 4 +- src/pages/chat/ChatRoom.jsx | 167 +++++++++-------- src/pages/join/JoinPage.jsx | 182 +++++++++++++++++++ src/pages/join/styled/JoinPage.styled.js | 94 ++++++++++ vite.config.js | 3 + 10 files changed, 415 insertions(+), 88 deletions(-) delete mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 src/api/JoinInfoPost.js create mode 100644 src/api/instanceAuth.js create mode 100644 src/pages/join/JoinPage.jsx create mode 100644 src/pages/join/styled/JoinPage.styled.js diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 03d9549..0000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/api/ChatMessageCall.js b/src/api/ChatMessageCall.js index b7bb3ef..e9ae5c2 100644 --- a/src/api/ChatMessageCall.js +++ b/src/api/ChatMessageCall.js @@ -15,7 +15,7 @@ export const getChatMessages = async (roomUUID, page = 0, size = 10) => { }); return response.data; } catch (error) { - console.error("Error fetching chat messages!:", error.message); + console.error("채팅방 메세지 불러오기 실패:", error.message); throw error; } }; \ No newline at end of file diff --git a/src/api/JoinInfoPost.js b/src/api/JoinInfoPost.js new file mode 100644 index 0000000..3fff134 --- /dev/null +++ b/src/api/JoinInfoPost.js @@ -0,0 +1,14 @@ +// src/utils/api.js +import { instance } from "./instanceAuth"; // 설정된 Axios 인스턴스 임포트 + +export async function postMemberData(data) { + const url = `/api/auth/member?name=${encodeURIComponent(data.koreanName)}`; + + try { + const response = await instance.post(url, data); // Axios 인스턴스 사용 + return response.data; // 서버로부터 받은 응답 데이터를 반환 + } catch (error) { + console.error("회원정보 보내기 실패:", error); + throw error; // 오류를 호출자에게 다시 던짐 + } +} diff --git a/src/api/instanceAuth.js b/src/api/instanceAuth.js new file mode 100644 index 0000000..06f74f0 --- /dev/null +++ b/src/api/instanceAuth.js @@ -0,0 +1,29 @@ +import axios from "axios"; + +// Axios 인스턴스 생성 +export const instance = axios.create({ + baseURL: import.meta.env.VITE_AUTH_BASE_URL, + withCredentials: true, + headers: { + "Content-Type": "application/json", + }, + timeout: 10000, // 10초 타임아웃 설정 +}); + +// 요청 인터셉터 추가 +instance.interceptors.request.use( + (config) => config, + (error) => Promise.reject(error) +); + +// 응답 인터셉터 추가 +instance.interceptors.response.use( + (response) => response, + (error) => { + if (error.code === "ECONNABORTED") { + console.log("Request timeout"); + window.location.href = "/error"; // 타임아웃 시 에러 페이지로 리디렉션 + } + return Promise.reject(error); + } +); diff --git a/src/components/Common/Header.jsx b/src/components/Common/Header.jsx index 68e2d24..3cf7a8e 100644 --- a/src/components/Common/Header.jsx +++ b/src/components/Common/Header.jsx @@ -21,7 +21,7 @@ function Header() { 카부 게시판 카부 프로젝트 - 카부 편의 + 카부 편의 카부 커넥션 diff --git a/src/pages/Homepage/HomePage.jsx b/src/pages/Homepage/HomePage.jsx index 077de8d..22ae10c 100644 --- a/src/pages/Homepage/HomePage.jsx +++ b/src/pages/Homepage/HomePage.jsx @@ -1,9 +1,9 @@ import React from "react"; import Layout from "../../components/Common/Layout"; -import ChatMain from "../../pages/chat/ChatMain"; + function HomePage() { return ( - +

햄스터

햄스터

햄스터

diff --git a/src/pages/chat/ChatRoom.jsx b/src/pages/chat/ChatRoom.jsx index a845f8a..4c5f6fc 100644 --- a/src/pages/chat/ChatRoom.jsx +++ b/src/pages/chat/ChatRoom.jsx @@ -1,17 +1,18 @@ import React, { useEffect, useState } from "react"; -import io from "socket.io-client"; +import * as Stomp from 'stompjs'; +import SockJS from "sockjs-client"; import * as styles from "./styled/ChatRoom.styled"; import Text from "../../components/Common/Text"; import ChatMessage from "./ChatMessage.jsx"; import { getChatMessages } from "../../api/ChatMessageCall.js"; const ChatRoom = (props) => { - const { uuid, name } = props; - const [messages, setMessages] = useState([]); - const [message, setMessage] = useState(""); - const [socket, setSocket] = useState(null); + const { uuid, name } = props; + const [messages, setMessages] = useState([]); + const [message, setMessage] = useState(""); + const [stompClient, setStompClient] = useState(null); - const currentUsername = "pjh2"; // 현재 사용자를 pjh2로 가정 + const currentUsername = "pjh2"; // 현재 사용자를 pjh2로 가정 const roomId = props.uuid; @@ -63,80 +64,90 @@ const ChatRoom = (props) => { ]); }); - return () => { - if (newSocket) { - newSocket.disconnect(); - console.log("WebSocket 연결 해제 되었습니다!"); - } - }; - }, [uuid]); // uuid 변경될 때마다 재연결 - - const sendMessage = () => { - if (message.trim() === "" || !socket || !uuid) { - return; - } - - const chatMessage = { - chatRoomUUID: uuid, - username: currentUsername, // 현재 접속한 사용자 - nickname: "UserNickName", - message: message, + return () => { + if (client) { + client.disconnect(() => { + console.log("WebSocket 연결 해제 되었습니다!"); + }); + } + }; + }, [uuid]); // uuid 변경될 때마다 재연결 + + const sendMessage = () => { + if (message.trim() === "" || !stompClient || !uuid) { + return; + } + + const chatMessage = { + chatRoomUUID: uuid, + username: currentUsername, // 현재 접속한 사용자 + nickname: "UserNickName", + message: message, + }; + + stompClient.send("/pub/messages", {}, JSON.stringify(chatMessage)); + + setMessages(prevMessages => { + if (Array.isArray(prevMessages)) { + return [ + ...prevMessages, + { + id: Date.now(), // 임시로 고유 ID를 부여 + user: chatMessage.username, + text: chatMessage.message, + time: new Date().toLocaleTimeString(), + isCurrentUser: true, // 현재 사용자가 보낸 메시지이므로 true + } + ]; + } else { + return [{ + id: Date.now(), + user: chatMessage.username, + text: chatMessage.message, + time: new Date().toLocaleTimeString(), + isCurrentUser: true, + }]; + } + }); + + setMessage(""); }; - socket.emit("message", chatMessage); - - setMessages((prevMessages) => [ - ...prevMessages, - { - id: Date.now(), // 임시로 고유 ID를 부여 - user: chatMessage.username, - text: chatMessage.message, - time: new Date().toLocaleTimeString(), - isCurrentUser: true, // 현재 사용자가 보낸 메시지이므로 true - }, - ]); - - setMessage(""); - }; - - return ( - - - - {name} - - - - {Array.isArray(messages) && - messages.map((each, id) => ( - - ))} - - - - - setMessage(e.target.value)} - onKeyDown={(e) => e.key === "Enter" && sendMessage()} - > - - {">"} - - - ); + return ( + + + {name} + + + {Array.isArray(messages) && messages.map((each, id) => ( + + ))} + + + + + setMessage(e.target.value)} + onKeyDown={(e) => e.key === 'Enter' && sendMessage()} + > + + {'>'} + + + ); }; export default ChatRoom; diff --git a/src/pages/join/JoinPage.jsx b/src/pages/join/JoinPage.jsx new file mode 100644 index 0000000..30d177e --- /dev/null +++ b/src/pages/join/JoinPage.jsx @@ -0,0 +1,182 @@ +import React, {useState} from "react"; +import Layout from "../../components/Common/Layout"; +import * as styles from "../join/styled/JoinPage.styled.js"; +import Text from "@/components/Common/Text.jsx"; +import {postMemberData} from '../../api/JoinInfoPost.js' +import {ContentLineTitleWrapper} from "../join/styled/JoinPage.styled.js"; + +function JoinPage(){ + const [englishName, setEnglishName] = useState(""); + const [koreaName, setKoreaName] = useState(""); + const [classNum, setclassNum] = useState(""); + const [team, setTeam] = useState(""); + const [course, setCourse] = useState(""); + + const handleTeamSelect = (selectedTeam)=>{ + + setTeam(selectedTeam); + } + + const handleSubmit = async () =>{ + const IntClassNum = parseInt(classNum, 10); + + if(isNaN(IntClassNum)){ + alert("기수를 숫자로 입력하세요!"); + return; + } + + const data = { + englishName, + koreaName, + classNum:IntClassNum, + course, + }; + console.log(data); + + try { + const result = await postMemberData(data); // API 유틸리티 파일의 함수 호출 + console.log("회원정보 보내기 성공!:", result); + alert("회원 정보가 성공적으로 전송되었습니다."); + } catch (error) { + alert("오류가 발생했습니다. 다시 시도해주세요."); + } + + }; + + return( + + + + + + 회원가입: 세부 정보 입력 + + + + + + + + + + + setEnglishName(e.target.value)} + + > + + + + + + + + setKoreaName(e.target.value)} + > + + + + + + + + + setclassNum(e.target.value)} + > + + + + + + + + + setCourse("FULLSTACK")}> + + + setCourse("AI")}> + + + setCourse("CLOUD")}> + + + + + + + + + + + + setTeam(e.target.value)} + + > + + + + + + + + + + + + + ) +}; + +export default JoinPage; \ No newline at end of file diff --git a/src/pages/join/styled/JoinPage.styled.js b/src/pages/join/styled/JoinPage.styled.js new file mode 100644 index 0000000..6c3f576 --- /dev/null +++ b/src/pages/join/styled/JoinPage.styled.js @@ -0,0 +1,94 @@ +/** @jsxImportSource @emotion/react */ +import styled from "@emotion/styled"; +import {css} from "@emotion/react"; + +export const TotalWrapper = styled.div` + display: flex; + flex-direction: column; + width: 90%; + height: 60vh; + align-items: center; + justify-content: center; +`; +export const TitleWrapper = styled.div` + display: flex; + flex-direction: column; + width: 100%; + height: 10%; + align-items: flex-start; + justify-content: center; +;`; + +export const Title = styled.h2` + +`; + +export const InnerWrapper = styled.div` + display: flex; + flex-direction: column; + width: 100%; + height: 90%; + align-items: center; + justify-content: center; + + border-bottom: 2px solid black; + border-top: 2px solid black; +`; + +export const ContentWrapper = styled.div` + display: flex; + flex-direction: column; + width: 60%; + height: 90%; + align-items: center; + justify-content: center; +`; + +export const ContentLineWrapper = styled.div` + display: flex; + flex-direction: row; + width: 60%; + height: 15%; + align-items: center; + justify-content: space-between; + margin: 5px; +`; +export const ContentLineTitleWrapper = styled.div` +width: 100px; +`; +export const ContentLineWrapper2 = styled.div` + display: flex; + flex-direction: row; + width: 60%; + height: 10%; + align-items: center; + justify-content: center; + margin: 5px; + background-color: beige; +`; +export const InputWrapper = styled.div` + display: flex; + align-items: center; + justify-content:center ; + width: 70%; + height: 50%; + +`; + +export const Input = styled.input` + width: 80%; + height: 95%; + border: 1.5px solid black; + outline: none; + + font-size: 20px; +`; + +export const TeamButton = styled.button` +width: 25%; + height: 100%; + border-radius: 15px; + background-color:#FFF7AE; + border: 2px solid black; + margin: 5px; +` diff --git a/vite.config.js b/vite.config.js index cedfe81..6d32319 100644 --- a/vite.config.js +++ b/vite.config.js @@ -9,4 +9,7 @@ export default defineConfig({ "@": "/src", }, }, + define: { + global: 'window', // 글로벌 변수를 브라우저 환경에서 사용할 수 있도록 설정 + }, });