Skip to content

Commit

Permalink
Merge pull request #1 from jinjoo-jung/chat
Browse files Browse the repository at this point in the history
Chat
  • Loading branch information
jinjoo-jung authored Nov 18, 2023
2 parents d7d4a8a + 4151c4e commit c295342
Show file tree
Hide file tree
Showing 26 changed files with 224 additions and 92 deletions.
112 changes: 111 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,111 @@
# 마피아 게임
# Mafia

- 🗓 기간: 2023.11.06 ~ 2023.11.16
- Socket.io의 양방향 통신을 활용한 채팅게임

## 🔍️ <주요 기능>

- 존재하는 모든 게임 방들의 정보를 받아 페이지에 렌더링
- 특정 게임방에 접속 시 제공받은 api와 추가 배포한 서버 api를 활용해 게임에 필요한 데이터를 요청 및 저장
- Socket 연결을 통한 게임 참가자들끼리의 채팅
- 추가 서버 api를 활용한 투표 시스템
- 투표 결과를 바탕으로 서버 데이터를 수정하고 결과를 화면에 렌더링

## 👭 참여 인원 및 담당 기능

<table>
<thead>
<tr>
<th align="center"> 팀장 | 최선파 </th>
<th align="center"> 팀원 | 남궁종민 </th>
<th align="center"> 팀원 | 정진주 </th>
<th align="center"> 팀원 | 김소정 </th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">
<a target="_blank" rel="noopener noreferrer nofollow" href="https://github.com/noSPkeepgoing">
<img src="https://avatars.githubusercontent.com/u/125979833?v=4" width="100" style="max-width: 100%;">
</a>
</td>
<td align="center">
<a target="_blank" rel="noopener noreferrer nofollow" href="https://github.com/NamgungJongMin">
<img src="https://avatars.githubusercontent.com/u/100336573?v=4" width="100" style="max-width: 100%;">
</a>
</td>
<td align="center">
<a target="_blank" rel="noopener noreferrer nofollow" href="https://github.com/jinjoo-jung">
<img src="https://avatars.githubusercontent.com/u/85981963?v=4" width="100" style="max-width: 100%;">
</a>
</td>
<td align="center">
<a target="_blank" rel="noopener noreferrer nofollow" href="https://github.com/KSJT">
<img src="https://avatars.githubusercontent.com/u/118329943?v=4" width="100" style="max-width: 100%;">
</a>
</td>
</tr>
<tr>
<td align="center">
<a href="https://github.com/noSPkeepgoing">@noSPkeepgoing</a>
</td>
<td align="center">
<a href="https://github.com/NamgungJongMin">@NamgungJongMin</a>
</td>
<td align="center">
<a href="https://github.com/jinjoo-jung">@jinjoo-jung</a>
</td>
<td align="center">
<a href="https://github.com/KSJT">@KSJT</a>
</td>
</tr>
<tr>
<td>
<ul>
<li>초기 개발 환경 세팅</li>
<li>게임 투표 기능</li>
<li>게임 진행 사항 및 결과 페이지</li>
</ul>
</td>
<td>
<ul>
<li>추가api 작성 및 서버 호스팅</li>
<li>로비 페이지</li>
<li>랜덤 역할 부여 기능</li>
<li>일렉트론 개발환경 세팅 및 데스크탑 앱 포맷팅</li>
</ul>
</td>
<td>
<ul>
<li>Socket 연결 및 통신</li>
<li>게임 채팅 기능</li>
<li>채팅방 페이지</li>
</ul>
</td>
<td>
<ul>
<li>JWT 토큰 발급</li>
<li>회원가입 및 로그인 기능</li>
<li>Redux toolkit을 활용한 상태관리</li>
</ul>
</td>
</tr>
</tbody>
</table>

## 🔍️ 기술 스택 및 라이브러리

<div style="display: flex;">
<img src="https://img.shields.io/badge/typescript-%23007ACC.svg?style=for-the-badge&logo=typescript&logoColor=white" />
<img src="https://img.shields.io/badge/vite-%646CFF.svg?style=for-the-badge&logo=vite&logoColor=white" />
<img src="https://img.shields.io/badge/react-%2320232a?style=for-the-badge&logo=react&logoColor=%2361DAFB" />
<img src="https://img.shields.io/badge/sass-CC6699?style=for-the-badge&logo=sass&logoColor=white" />
<img src="https://img.shields.io/badge/github-181717?style=for-the-badge&logo=github&logoColor=white" />
<img src="https://img.shields.io/badge/pockethost-%B8DBE4.svg?style=for-the-badge&logo=pocketbase" />
<img src="https://img.shields.io/badge/Redux/toolkit-%23039BE5.svg?style=for-the-badge&logo=Redux" />
<img src="https://img.shields.io/badge/socket.io-010101.svg?style=for-the-badge&logo=reactquery&logoColor=white" />
</div>

## 🎨 프로토타입 디자인

![image](https://github.com/NamgungJongMin/Mafia-team4/assets/100336573/5f2bbb4a-f62a-46e5-961c-eeb475b23b0a)
4 changes: 2 additions & 2 deletions src/api/idcheck.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const idCheck = async (id) => {
export const idCheck = async (id: string) => {
const result = await fetch('https://fastcampus-chat.net/check/id', {
method: 'POST',
headers: {
Expand All @@ -11,4 +11,4 @@ export const idCheck = async (id) => {
const res = response.isDuplicated;

return res;
}
};
2 changes: 0 additions & 2 deletions src/api/login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,3 @@ export const login = async (id: string, password: string) => {
return { error: '오류가 발생했습니다. 잠시 후 다시 시도해 주세요.' };
}
};


7 changes: 6 additions & 1 deletion src/api/signup.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
export const signup = async (id, password, name, character) => {
export const signup = async (
id: string,
password: string,
name: string,
character: string,
) => {
const data = {
id: id,
password: password,
Expand Down
1 change: 0 additions & 1 deletion src/components/chat/ChatHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from 'react';
import styles from '@styles/components/chatHeader.module.scss';
import { useNavigate } from 'react-router-dom';

Expand Down
6 changes: 4 additions & 2 deletions src/components/chat/ChatItem.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import styles from '@styles/components/chatItem.module.scss';
import fastRequest from '@api/fastRequest';
import { useAppSelector } from '@/hooks/redux';
Expand Down Expand Up @@ -36,7 +36,9 @@ const ChatItem = ({
<img className={styles.chatItemImage} src={userInfo?.picture} />
<p className={styles.chatItemNickname}>{userInfo?.name}</p>
</div>
<span className={styles.chatItemText}>{text}</span>
<p className={Mymsg ? styles.selfChatItemText : styles.chatItemText}>
{text}
</p>
</div>
);
};
Expand Down
2 changes: 1 addition & 1 deletion src/components/common/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import '@styles/components/button.module.scss';

const Button = ({ text }) => {
const Button = () => {
return <div>Button</div>;
};

Expand Down
2 changes: 1 addition & 1 deletion src/components/common/GameHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import styles from '@styles/components/gameHeader.module.scss';
import { useNavigate } from 'react-router-dom';

Expand Down
2 changes: 0 additions & 2 deletions src/components/lobby/Pagination.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import React from 'react';

import refresh from '@assets/images/refresh.png';
import styles from '@styles/components/lobby/pagination.module.scss';

Expand Down
19 changes: 0 additions & 19 deletions src/components/lobby/Room.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,27 +72,8 @@ interface Props {
users: User[];
}

// interface UserInfo {
// user: User;
// }

interface User {
id: string;
name: string;
picture: string;
}

interface Game {
id: string;
chatId: string;
mafia: number;
vote: Vote[];
}

interface Vote {
count: number;
id: string;
name: string;
picture: string;
role: string;
}
16 changes: 0 additions & 16 deletions src/components/lobby/UserImg.tsx

This file was deleted.

12 changes: 6 additions & 6 deletions src/components/signup/SignupModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ const SignupModal: React.FC<SignupModalProps> = ({ handleModal }) => {
</div>
<div className={styles.singupModal__right_btn}>
<span onClick={() => goNext()} className="material-symbols-outlined">
</span>
</div>
</div>
Expand All @@ -163,13 +163,13 @@ type SignupModalProps = {
handleModal: () => void;
};

interface GhostRecord {
id: string,
filename: string,
field: string,
interface GhostRecord {
id: string;
filename: string;
field: string;
}

interface Ghost {
id: string;
fileUrl: string;
}
}
2 changes: 1 addition & 1 deletion src/components/vote/GhostList.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import styles from '@styles/components/ghostList.module.scss';
import { Ghost } from '@/pages/game/Vote';
import GhostItem from '@components/vote/GhostItem';
Expand Down
6 changes: 3 additions & 3 deletions src/hooks/useForm.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useState, ChangeEvent } from "react";
import { useState, ChangeEvent } from 'react';

export const useForm = (): UseFormReturnType => {
const [value, setValue] = useState<string>("");
const [value, setValue] = useState<string>('');
const onChange = (event: ChangeEvent<HTMLInputElement>): void => {
setValue(event.target.value);
};
Expand All @@ -10,5 +10,5 @@ export const useForm = (): UseFormReturnType => {

type UseFormReturnType = [
string,
(event: ChangeEvent<HTMLInputElement>) => void
(event: ChangeEvent<HTMLInputElement>) => void,
];
17 changes: 10 additions & 7 deletions src/pages/auth/Signup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const Signup = () => {
const [password, onChangePassword] = useForm();
const [assurer, onChangeAssurer] = useForm();
const [errors, setErrors] = useState<Errors>({});
const [profileError, setProfileError] = useState("")
const [profileError, setProfileError] = useState('');
const [invalidId, setInvalidId] = useState(false);
const [isModalOpen, setIsModalOpen] = useState(false);
const character = useAppSelector((state) => state.selectedGhost);
Expand All @@ -37,7 +37,7 @@ const Signup = () => {
const validId = await idCheck(user.id);
// console.log(validId);
if (character === '') {
setProfileError("프로필 캐릭터를 선택해주세요.")
setProfileError('프로필 캐릭터를 선택해주세요.');
} else if (!validId && character) {
await signup(id, password, name, character);
navigate('/');
Expand All @@ -54,7 +54,6 @@ const Signup = () => {
: `url("/src/assets/images/profile.jpeg")`,
};


const handleModal: () => void = () => {
setIsModalOpen(false);
};
Expand All @@ -68,8 +67,8 @@ const Signup = () => {
className={styles.signup__profile}></button>
<p>프로필 선택</p>
{profileError && (
<span className={styles.signup__form_error}>{profileError}</span>
)}
<span className={styles.signup__form_error}>{profileError}</span>
)}
</div>
<div className={styles.signup__container}>
<form className={styles.signup__form}>
Expand All @@ -83,7 +82,9 @@ const Signup = () => {
<span className={styles.signup__form_error}>{errors?.id}</span>
)}
{invalidId && (
<span className={styles.signup__form_error}>이미 존재하는 아이디입니다.</span>
<span className={styles.signup__form_error}>
이미 존재하는 아이디입니다.
</span>
)}
<input
type="text"
Expand All @@ -101,7 +102,9 @@ const Signup = () => {
onChange={onChangePassword}
/>
{errors?.password && (
<span className={styles.signup__form_error}>{errors?.password}</span>
<span className={styles.signup__form_error}>
{errors?.password}
</span>
)}
<input
type="password"
Expand Down
2 changes: 1 addition & 1 deletion src/pages/game/Hanging.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import styles from '@styles/pages/hanging.module.scss';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { getGameData } from '@/api/vote';
Expand Down
1 change: 0 additions & 1 deletion src/pages/game/Night.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from 'react';
import styles from '@styles/pages/night.module.scss';
import GameHeader from '@components/common/GameHeader';
import { useSearchParams } from 'react-router-dom';
Expand Down
2 changes: 1 addition & 1 deletion src/pages/game/Reset.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect } from 'react';
import { useEffect } from 'react';
import styles from '@styles/pages/reset.module.scss';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { getGameData, patchGameResult } from '@/api/vote';
Expand Down
4 changes: 2 additions & 2 deletions src/pages/game/Result.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import styles from '@styles/pages/result.module.scss';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { getGameData } from '@/api/vote';
Expand Down Expand Up @@ -48,7 +48,7 @@ const Result = () => {
}, []);

const handleClick = async () => {
await fastRequest.leaveChat(chatId as string, accessToken);
await fastRequest.leaveChat(chatId as string, accessToken as string);
navigate('/lobby');
};

Expand Down
10 changes: 7 additions & 3 deletions src/pages/game/Role.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ const Role = () => {
});

setRole('mafia');
setTimeout(() => {
navigate(`/chat?chatId=${chatId}&pocketId=${pocketId}&role=mafia`);
}, 6000);
} else {
setTimeout(() => {
navigate(`/chat?chatId=${chatId}&pocketId=${pocketId}&role=citizen`);
}, 6000);
}
} catch (error) {
console.error('check mafia error');
Expand All @@ -55,9 +62,6 @@ const Role = () => {
useEffect(() => {
setMafia();
setTimeout(() => setIsLoding(false), 3000);
setTimeout(() => {
navigate(`/chat?chatId=${chatId}&pocketId=${pocketId}&role=${role}`);
}, 6000);
}, []);

return (
Expand Down
Loading

0 comments on commit c295342

Please sign in to comment.