diff --git a/package-lock.json b/package-lock.json
index e3a1a2f9..34c0a9a4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16,6 +16,8 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.18.0",
+ "recoil": "^0.7.7",
+ "socket.io-client": "^4.7.2",
"styled-components": "^6.1.0"
},
"devDependencies": {
@@ -2031,6 +2033,11 @@
"node": ">=14.0.0"
}
},
+ "node_modules/@socket.io/component-emitter": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
+ "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
+ },
"node_modules/@swc/core": {
"version": "1.3.96",
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.96.tgz",
@@ -2831,7 +2838,6 @@
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
- "dev": true,
"dependencies": {
"ms": "2.1.2"
},
@@ -2887,6 +2893,26 @@
"node": ">=6.0.0"
}
},
+ "node_modules/engine.io-client": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.2.tgz",
+ "integrity": "sha512-CQZqbrpEYnrpGqC07a9dJDz4gePZUgTPMU3NKJPSeQOyw27Tst4Pl3FemKoFGAlHzgZmKjoRmiJvbWfhCXUlIg==",
+ "dependencies": {
+ "@socket.io/component-emitter": "~3.1.0",
+ "debug": "~4.3.1",
+ "engine.io-parser": "~5.2.1",
+ "ws": "~8.11.0",
+ "xmlhttprequest-ssl": "~2.0.0"
+ }
+ },
+ "node_modules/engine.io-parser": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz",
+ "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
"node_modules/error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -3429,6 +3455,11 @@
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
"dev": true
},
+ "node_modules/hamt_plus": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/hamt_plus/-/hamt_plus-1.0.2.tgz",
+ "integrity": "sha512-t2JXKaehnMb9paaYA7J0BX8QQAY8lwfQ9Gjf4pg/mk4krt+cmwmU652HOoWonf+7+EQV97ARPMhhVgU1ra2GhA=="
+ },
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -3747,8 +3778,7 @@
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "dev": true
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/nanoid": {
"version": "3.3.7",
@@ -4185,6 +4215,25 @@
}
}
},
+ "node_modules/recoil": {
+ "version": "0.7.7",
+ "resolved": "https://registry.npmjs.org/recoil/-/recoil-0.7.7.tgz",
+ "integrity": "sha512-8Og5KPQW9LwC577Vc7Ug2P0vQshkv1y3zG3tSSkWMqkWSwHmE+by06L8JtnGocjW6gcCvfwB3YtrJG6/tWivNQ==",
+ "dependencies": {
+ "hamt_plus": "1.0.2"
+ },
+ "peerDependencies": {
+ "react": ">=16.13.1"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ }
+ }
+ },
"node_modules/regenerator-runtime": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
@@ -4336,6 +4385,32 @@
"node": ">=8"
}
},
+ "node_modules/socket.io-client": {
+ "version": "4.7.2",
+ "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.2.tgz",
+ "integrity": "sha512-vtA0uD4ibrYD793SOIAwlo8cj6haOeMHrGvwPxJsxH7CeIksqJ+3Zc06RvWTIFgiSqx4A3sOnTXpfAEE2Zyz6w==",
+ "dependencies": {
+ "@socket.io/component-emitter": "~3.1.0",
+ "debug": "~4.3.2",
+ "engine.io-client": "~6.5.2",
+ "socket.io-parser": "~4.2.4"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/socket.io-parser": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
+ "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
+ "dependencies": {
+ "@socket.io/component-emitter": "~3.1.0",
+ "debug": "~4.3.1"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
"node_modules/source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
@@ -4652,6 +4727,34 @@
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true
},
+ "node_modules/ws": {
+ "version": "8.11.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
+ "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/xmlhttprequest-ssl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz",
+ "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
diff --git a/package.json b/package.json
index 06619bbc..80109d87 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,8 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.18.0",
+ "recoil": "^0.7.7",
+ "socket.io-client": "^4.7.2",
"styled-components": "^6.1.0"
},
"devDependencies": {
diff --git a/src/App.tsx b/src/App.tsx
index a6d5dd6d..7b9b6a70 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -2,14 +2,17 @@ import { BrowserRouter } from 'react-router-dom';
import { ChakraProvider } from '@chakra-ui/react';
import MainRouter from './router/MainRouter';
import LoginRouter from './router/LoginRouter';
+import { RecoilRoot } from 'recoil';
function App() {
return (
-
-
-
-
+
+
+
+
+
+
);
}
diff --git a/src/api/index.ts b/src/api/index.ts
index c932f7fa..51fd4e03 100644
--- a/src/api/index.ts
+++ b/src/api/index.ts
@@ -2,6 +2,7 @@ import axios from 'axios';
import { CONTENT_TYPE, SERVER_ID, SERVER_URL } from '../constant';
import { JoinData } from '../interfaces/interface';
+
const client = axios.create({
baseURL: SERVER_URL,
headers: {
@@ -30,4 +31,61 @@ export const getAllUsers = async (accessToken: string) => {
},
});
return res;
+
+export const createGameRooms = async (
+ accessToken: string,
+ name: string,
+ users: string[],
+ isPrivate: boolean,
+) => {
+ const authData = {
+ name,
+ users,
+ isPrivate,
+ };
+ try {
+ const response = await axios.post(`${SERVER_URL}/chat`, authData, {
+ headers: {
+ 'content-type': CONTENT_TYPE,
+ serverId: SERVER_ID,
+ Authorization: `Bearer ${accessToken}`,
+ },
+ });
+ return response.data;
+ } catch (error) {
+ console.log(error);
+ }
+};
+
+export const getAllGameRooms = async (accessToken: string) => {
+ const response = await axios.get(`${SERVER_URL}/chat/all`, {
+ headers: {
+ 'content-type': CONTENT_TYPE,
+ serverId: SERVER_ID,
+ Authorization: `Bearer ${accessToken}`,
+ },
+ });
+ return response.data;
+};
+
+export const participateGameRoom = async (
+ chatId: string,
+ accessToken: string,
+) => {
+ const authData = {
+ chatId,
+ };
+ const response = await axios.patch(
+ `${SERVER_URL}/chat/participate`,
+ authData,
+ {
+ headers: {
+ 'content-type': CONTENT_TYPE,
+ serverId: SERVER_ID,
+ Authorization: `Bearer ${accessToken}`,
+ },
+ },
+ );
+ console.log(response.data);
+ return response.data;
};
diff --git a/src/api/socket.ts b/src/api/socket.ts
new file mode 100644
index 00000000..de619507
--- /dev/null
+++ b/src/api/socket.ts
@@ -0,0 +1,11 @@
+import { SERVER_ID, CONTENT_TYPE, SERVER_URL } from '../constant';
+import io from 'socket.io-client';
+export const socketLogin = (accessToken: string) => {
+ const socket = io(`${SERVER_URL}/server`, {
+ extraHeaders: {
+ Authorization: `Bearer ${accessToken}`,
+ serverId: SERVER_ID,
+ },
+ });
+ return socket;
+};
diff --git a/src/components/layout/checkGameRoom.tsx b/src/components/layout/checkGameRoom.tsx
new file mode 100644
index 00000000..55eda2e8
--- /dev/null
+++ b/src/components/layout/checkGameRoom.tsx
@@ -0,0 +1,54 @@
+import { useEffect } from 'react';
+import { useRecoilState } from 'recoil';
+import { allRoomState } from '../../states/atom';
+import { getAllGameRooms, participateGameRoom } from '../../api';
+import { useNavigate } from 'react-router-dom';
+
+const CheckGameRoom = () => {
+ const token: any = localStorage.getItem('jwt');
+ const navigate = useNavigate();
+ const [allRooms, setAllRooms] = useRecoilState(allRoomState);
+ const fetchData = async () => {
+ try {
+ const allRoomsData = await getAllGameRooms(token);
+ setAllRooms(allRoomsData.chats);
+ } catch (error) {
+ console.error('데이터 가져오기 오류:', error);
+ }
+ };
+
+ useEffect(() => {
+ fetchData();
+ }, [allRooms.length]);
+
+ if (allRooms.length === 0) {
+ return
No rooms available or an error occurred.
;
+ }
+
+ const handleParticipate = async (numberOfPeople: number, chatId: any) => {
+ if (numberOfPeople === 4) {
+ alert('방이 꽉 찼어요.');
+ } else {
+ await participateGameRoom(chatId, token);
+ navigate(`/room/${chatId}`);
+ }
+ };
+
+ return (
+ <>
+
+ {allRooms.map((element, index) => (
+ handleParticipate(element.users.length, element.id)}>
+ {element.name}
+
{element.users.length}
+ {element.users.length === 4 &&
Four users in this room
}
+
{element.users[0].id}
+
+ ))}
+ >
+ );
+};
+
+export default CheckGameRoom;
diff --git a/src/components/layout/createGameRoom.tsx b/src/components/layout/createGameRoom.tsx
new file mode 100644
index 00000000..598ee99c
--- /dev/null
+++ b/src/components/layout/createGameRoom.tsx
@@ -0,0 +1,78 @@
+import React, { useEffect, useState } from 'react';
+import { useNavigate } from 'react-router-dom';
+import { createGameRooms } from '../../api';
+import { io } from 'socket.io-client';
+import { SERVER_URL, CONTENT_TYPE, SERVER_ID } from '../../constant';
+import { useRecoilState } from 'recoil';
+import { allRoomState } from '../../states/atom';
+
+const CreateGameRoom = () => {
+ const [allRooms, setAllRooms] = useRecoilState(allRoomState);
+ const navigate = useNavigate();
+ const [name, setName] = useState('');
+ const [users, setUsers] = useState([]);
+ const [isPrivate, setIsPrivate] = useState(false);
+ const token: any = localStorage.getItem('jwt');
+
+ const onChange = (e: React.ChangeEvent) => {
+ const { value, name } = e.target;
+ console.log(value, name);
+ if (value === 'Private') {
+ setIsPrivate(true);
+ } else {
+ setIsPrivate(false);
+ }
+ };
+
+ const onChangeName = (e: React.ChangeEvent) => {
+ setName(e.target.value);
+ };
+
+ const submit = async (e: React.FormEvent) => {
+ e.preventDefault();
+ const check = await createGameRooms(token, name, users, isPrivate);
+ if (check === undefined) {
+ alert('중복된 방이 있습니다.');
+ } else {
+ alert('방 생성 성공.');
+ const socket = io(`${SERVER_URL}/chat?chatId=${check.id}`, {
+ extraHeaders: {
+ Authorization: `Bearer ${token}`,
+ 'content-type': CONTENT_TYPE,
+ serverId: SERVER_ID,
+ },
+ });
+ console.log(socket.connected);
+ socket.on('message-to-client', (messageObject: any) => {
+ console.log(messageObject);
+ });
+
+ setAllRooms([...allRooms, check]);
+
+ navigate(`/room/:${check.id}`);
+ }
+ };
+
+ return (
+ <>
+ CreateGameRoom
+
+ >
+ );
+};
+
+export default CreateGameRoom;
diff --git a/src/components/layout/onineUserList.tsx b/src/components/layout/onineUserList.tsx
new file mode 100644
index 00000000..1942262c
--- /dev/null
+++ b/src/components/layout/onineUserList.tsx
@@ -0,0 +1,41 @@
+// import { } from '../../pages/login/userLogin';
+
+// const OnlineUserList = async () => {
+// const socket = sendingClient;
+// if (socket) {
+// socket.on('message-to-client', (messageObject: any) => {
+// console.log(messageObject.data);
+// });
+// } else {
+// console.error(
+// 'Socket is null. Socket connection might not be established yet.',
+// );
+// }
+// // const [allOnlineUsers, setAllOnlineUsers] = useRecoilState(onlineUserState);
+// // const token: any = localStorage.getItem('jwt');
+
+// // useEffect(() => {
+// // const socket = socketLogin(token);
+
+// // const handleUsersUpdate = (responseData: any) => {
+// // const usersArray = Array.isArray(responseData) ? responseData : [];
+// // setAllOnlineUsers(usersArray);
+// // };
+
+// // socket.on('users-server-to-client', handleUsersUpdate);
+
+// // return () => {
+// // socket.off('users-server-to-client', handleUsersUpdate);
+// // };
+// // }, [setAllOnlineUsers, token]);
+
+// // console.log(allOnlineUsers);
+
+// return (
+// <>
+// 1
+// >
+// );
+// };
+
+// export default OnlineUserList;
diff --git a/src/components/layout/userList.tsx b/src/components/layout/userList.tsx
new file mode 100644
index 00000000..e1916193
--- /dev/null
+++ b/src/components/layout/userList.tsx
@@ -0,0 +1,34 @@
+import { useEffect } from 'react';
+import { useRecoilState } from 'recoil';
+import { allUserState } from '../../states/atom';
+import { getAllUsers } from '../../api';
+
+const UserList = () => {
+ const [allUsers, setAllUsers] = useRecoilState(allUserState);
+ // const [allRooms, setAllRooms] = useRecoilState(allRoomState);
+ const token: any = localStorage.getItem('jwt');
+ // const allUsers = useRecoilValue(allUserState);
+ console.log(allUsers);
+ useEffect(() => {
+ async function fetchData() {
+ try {
+ const allUsersData = await getAllUsers(token);
+ setAllUsers(allUsersData);
+ } catch (error) {
+ console.error('데이터 가져오기 오류:', error);
+ }
+ }
+
+ fetchData();
+ }, []);
+
+ return (
+ <>
+ {allUsers.map((element, index) => (
+ {element.name}
+ ))}
+ >
+ );
+};
+
+export default UserList;
diff --git a/src/pages/lobby/gameLobby.tsx b/src/pages/lobby/gameLobby.tsx
index 201ed431..051bc348 100644
--- a/src/pages/lobby/gameLobby.tsx
+++ b/src/pages/lobby/gameLobby.tsx
@@ -1,4 +1,7 @@
-import { getAllUsers } from '../../api/index';
+import CreateGameRoom from '../../components/layout/createGameRoom';
+import CheckGameRoom from '../../components/layout/checkGameRoom';
+// import OnlineUserList from '../../components/layout/onineUserList';
+// import UserList from '../../components/layout/userList';
const GameLobby = () => {
const handleGetAllUsers = async (e: React.FormEvent) => {
e.preventDefault();
@@ -20,9 +23,34 @@ const GameLobby = () => {
}
};
+ // const [allUsers, setAllUsers] = useRecoilState(allUserState);
+ // const [allRooms, setAllRooms] = useRecoilState(allRoomState);
+ // const token: any = localStorage.getItem('jwt');
+
+ // useEffect(() => {
+ // async function fetchData() {
+ // try {
+ // const allUsersData = await getAllUsers(token);
+ // setAllUsers(allUsersData);
+ // const allRoomsData = await getAllGameRooms(token);
+ // setAllRooms(allRoomsData.chats);
+ // } catch (error) {
+ // console.error('데이터 가져오기 오류:', error);
+ // }
+ // }
+
+
+ // fetchData();
+ // }, []);
return (
<>
-
+ {/* */}
+
+ {/* */}
+
+
+
+
>
);
};
diff --git a/src/pages/login/userLogin.tsx b/src/pages/login/userLogin.tsx
index 4dccaf15..10954bc8 100644
--- a/src/pages/login/userLogin.tsx
+++ b/src/pages/login/userLogin.tsx
@@ -1,4 +1,5 @@
import React, { useState } from 'react';
+
import { Link as ReactRouterLink, useNavigate } from 'react-router-dom';
import {
Center,
@@ -14,11 +15,13 @@ import {
import { postLogin } from '../../api/index';
+
const UserLogin = () => {
const navigate = useNavigate();
const [id, setId] = useState('');
const [password, setPassword] = useState('');
+ const token: any = localStorage.getItem('jwt');
const handleLoginSubmit = async (e: React.FormEvent) => {
e.preventDefault();
@@ -27,18 +30,7 @@ const UserLogin = () => {
const { accessToken, refreshToken } = res.data;
localStorage.setItem('accessToken', accessToken);
alert('로그인에 성공했습니다.');
- navigate('/lobby');
- } catch (e: any) {
- console.log(e.message);
- if (e.message === 'Request failed with status code 400') {
- alert('아이디를 확인해주세요.');
- } else if (e.message === 'Request failed with status code 401') {
- alert('비밀번호를 확인해주세요.');
- } else {
- alert('로그인에 실패했습니다.');
- }
- }
- };
+
return (
({
+ key: 'allUserState',
+ default: [],
+});
+
+export const allRoomState = atom
({
+ key: 'allRoomsState',
+ default: [],
+});
+
+export const onlineUserState = atom({
+ key: 'onlineUserState',
+ default: [],
+});