Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 55 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,50 +1,55 @@
# React + TypeScript + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh

## Expanding the ESLint configuration

If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:

- Configure the top-level `parserOptions` property like this:

```js
export default tseslint.config({
languageOptions: {
// other options...
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
},
})
```

- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked`
- Optionally add `...tseslint.configs.stylisticTypeChecked`
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config:

```js
// eslint.config.js
import react from 'eslint-plugin-react'

export default tseslint.config({
// Set the react version
settings: { react: { version: '18.3' } },
plugins: {
// Add the react plugin
react,
},
rules: {
// other rules...
// Enable its recommended rules
...react.configs.recommended.rules,
...react.configs['jsx-runtime'].rules,
},
})
```
## :pushpin: 프로젝트명
## CodeNameDavinci

> 보드게임 '다빈치코드'를 웹 게임으로 구현

## 📆 개발기간
2024년 12월 ~ 진행중

## 🕹 배포주소 : https://www.davincicodegame.store/home

## 🏢 아키텍쳐
<img src="https://github.com/user-attachments/assets/41ba4895-007a-4f21-8ea8-d24654e64da8">


## 📚 기술스택
<img src="https://img.shields.io/badge/react-61DAFB?style=for-the-badge&logo=react&logoColor=black"><img src="https://img.shields.io/badge/styledcomponents-DB7093?style=for-the-badge&logo=styledcomponents&logoColor=white"><img src="https://img.shields.io/badge/Typescript-3178C6?style=for-the-badge&logo=typescript&logoColor=white"><img src="https://img.shields.io/badge/axios-5A29E4?style=for-the-badge&logo=axios&logoColor=white"><img src="https://img.shields.io/badge/reactquery-FF4154?style=for-the-badge&logo=reactquery&logoColor=white"><img src="https://img.shields.io/badge/reacthookform-EC5990?style=for-the-badge&logo=reacthookform&logoColor=white"><img src="https://img.shields.io/badge/zod-3E67B1?style=for-the-badge&logo=Zod&logoColor=white"><img src="https://img.shields.io/badge/zustand-F36D00?style=for-the-badge&logo=zustand&logoColor=white"><img src="https://img.shields.io/badge/socket.io-010101?style=for-the-badge&logo=socketdotio&logoColor=white">

## 🌄 화면구성
<img src = "https://github.com/user-attachments/assets/bc35c2a6-1f24-4886-9d4d-f3c29239be0d" with="150" height="150">
<img src = "https://github.com/user-attachments/assets/9c3f202d-29c3-448b-98a7-659e771c2b8b" with="150" height="150">
<img src = "https://github.com/user-attachments/assets/d3e1c795-c94d-4dac-a1ca-b531eae00b01" with="150" height="150">
<img src = "https://github.com/user-attachments/assets/9e3ad62c-d895-4bef-9bf9-b1e8b249edf9" with="150" height="150">
<img src = "https://github.com/user-attachments/assets/220792f6-9584-4bf1-9b64-d883202331ce" with="150" height="150">
<img src = "https://github.com/user-attachments/assets/bd22ba48-d4ae-435e-82f5-c5f4f04ab039" with="150" height="150">



## 📺 게임플레이
...

## 🤗 맡은 역할

### 1⃣ 로그인 개발
JWT 인증: Access Token 관리

### 2⃣ 공통 컴포넌트 개발
#### Input 컴포넌트
react-hook-form,zod를 사용하여 입력 검증
에러 메시지, 포커스 기능 추가

#### Button 컴포넌트
상태별 스타일 적용ㅋ
클릭 이벤트 핸들링 최적화

### 3⃣ 게임 로직 개발
#### 핵심 로직 구현
게임 상태 관리 (시작, 진행, 종료)
플레이어 규칙 반영

### 4⃣ Socket 통신을 통한 UI/UX 개발
실시간 데이터 동기화
Socket.io 적용
게임 이벤트 처리


1 change: 1 addition & 0 deletions src/components/ui/card/chatting/ChattingStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ export const chatInputBoxContainer = styled.div`
display: flex;
flex-direction: column;
gap: 10px;
height: 100%;
`;
3 changes: 1 addition & 2 deletions src/components/ui/chatInput/chatInputStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import styled from "styled-components";
export const chatLog = styled.div`
flex-grow: 1;
font-size: 14px;
max-height: 290px;
overflow-y: scroll;
height: 100%;
`;

export const chatInput = styled.input`
Expand All @@ -31,5 +31,4 @@ export const chatInputBox = styled.div`
width: 100%;
display: flex;
gap: 10px;
height: 100%;
`;
4 changes: 2 additions & 2 deletions src/components/ui/modal/modalComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ export const modalComponents: Record<string, React.ReactNode> = {
selectWhiteBlack: <BigDeck />,
turnWaiting: <TurnWaiting />,
gameWaiting: <GameWaiting />,
GamrRoomJoinConfirm: (
selectTurn: <SelectTurn />,
gameRoomJoinConfirm: (
<Alert message="개임 방 만들기는 로그인 후 가능합니다." />
),
guessNumber: <GuessNumber />,
myTurn: <BigDeck />,
selectTurn: <SelectTurn />,
};
45 changes: 31 additions & 14 deletions src/components/ui/ranking/RankingList.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
import gold from "../../../assets/images/icon_gold.svg";
import silver from "../../../assets/images/icon_silver.svg";
import bronze from "../../../assets/images/icon_bronze.svg";
import { BronzeImage, GoldImage, SilverImage } from "./rankingListStyle";
import {
BronzeImage,
GoldImage,
Hr,
NickNameBox,
NicknameImage,
NickNameText,
RankingBox,
RankingNumber,
SilverImage,
} from "./rankingListStyle";
import profile from "../../../assets/images/image_profile_01.svg";

interface IRankingList {
nickname: string;
Expand All @@ -11,19 +22,25 @@ interface IRankingList {
export default function RankingList({ nickname, index }: IRankingList) {
return (
<div>
<p>
{index === 0 ? (
<GoldImage src={gold} alt="금메달" />
) : index === 1 ? (
<SilverImage src={silver} alt="은메달" />
) : index === 2 ? (
<BronzeImage src={bronze} alt="동메달" />
) : (
""
)}
</p>
<p>{nickname}</p>
<p>{index + 1}</p>
<RankingBox>
<NickNameBox>
<p>
{index === 0 ? (
<GoldImage src={gold} alt="금메달" />
) : index === 1 ? (
<SilverImage src={silver} alt="은메달" />
) : index === 2 ? (
<BronzeImage src={bronze} alt="동메달" />
) : (
""
)}
</p>
<NicknameImage src={profile} alt="닉네임 프로필" />
<NickNameText>{nickname}</NickNameText>
</NickNameBox>
<RankingNumber>{index + 1}</RankingNumber>
</RankingBox>
<Hr></Hr>
</div>
);
}
44 changes: 41 additions & 3 deletions src/components/ui/ranking/rankingListStyle.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,43 @@
import styled from "styled-components";

export const GoldImage = styled.img``;
export const SilverImage = styled.img``;
export const BronzeImage = styled.img``;
export const RankingBox = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
margin: 0px 44px 0px 61px;
`;
export const NickNameBox = styled.div`
display: flex;
gap: 20px;
`;
export const GoldImage = styled.img`
width: 30px;
height: 30px;
`;
export const SilverImage = styled.img`
width: 30px;
height: 30px;
`;
export const BronzeImage = styled.img`
width: 30px;
height: 30px;
`;
export const NicknameImage = styled.img`
width: 40px;
height: 40px;
`;
export const NickNameText = styled.div`
color: var(--gray-999);
font-size: 18px;
font-weight: 500;
`;
export const RankingNumber = styled.div`
color: var(--gray-999);
font-size: 24px;
font-weight: 600;
`;
export const Hr = styled.hr`
width: 400px;
height: 1px;
background: var(--gray-999);
`;
2 changes: 1 addition & 1 deletion src/pages/game/gameRoomList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default function GameRoomList() {

const onClickModalOpen = () => {
if (!accessToken || accessToken === null) {
openModal("GamrRoomJoinConfirm", "white");
openModal("gameRoomJoinConfirm", "white");
} else {
openModal("makeRoom", "white");
}
Expand Down
29 changes: 17 additions & 12 deletions src/pages/rank/RankingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,30 @@ import {
MainTextBox,
TrophyBox,
TrophyImage,
Wrapper,
} from "./rankingPageStyle";
import trophy from "../../assets/images/icon_trophy.svg";
import RankingList from "../../components/ui/ranking/RankingList";
// import RankingList from "../../components/ui/ranking/RankingList";

export default function RangkingPage() {
return (
<FullBox>
<TrophyBox>
<TrophyImage src={trophy} alt="랭킹 트로피 이미지" />
<H1>전체 랭킹</H1>
</TrophyBox>
<MainTextBox>
<div>닉네임</div>
<div>순위</div>
</MainTextBox>
<Hr />
{/* {data?.ranking.map((user, index) => (
<Wrapper>
<FullBox>
<TrophyBox>
<TrophyImage src={trophy} alt="랭킹 트로피 이미지" />
<H1>전체 랭킹</H1>
</TrophyBox>
<MainTextBox>
<div>닉네임</div>
<div>순위</div>
</MainTextBox>
<Hr />
{/* {data?.ranking.map((user, index) => (
<RankingList nickname={user.userNickname} index={index} />
))} */}
</FullBox>
<RankingList nickname="" index={0}></RankingList>
</FullBox>
</Wrapper>
);
}
4 changes: 4 additions & 0 deletions src/pages/rank/rankingPageStyle.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import styled from "styled-components";

export const Wrapper = styled.div`
display: flex;
justify-content: center;
`;
export const FullBox = styled.div`
width: 400px;
display: flex;
Expand Down
20 changes: 14 additions & 6 deletions src/routes/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Home from "@pages/home/Home";
import SignUpFinish from "@pages/user/signUp/SignUpFinish";
import Error from "@pages/error/Error";
import TestPage from "../pages/testpage/Testpage";
import MyPage from "../pages/mypage/myScorePage/MyPage";

export const router = createBrowserRouter([
{
Expand Down Expand Up @@ -58,13 +59,20 @@ export const router = createBrowserRouter([
],
},
{
path: "/user/mypage/checkPassword",
element: <CheckPassword />,
},
{
path: "/user/mypage/updateMyPage",
element: <UpdateMyPage />,
path: "/user/mypage",
element: <MyPage />,
children: [
{
path: "checkPassword",
element: <CheckPassword />,
},
{
path: "updateMyPage",
element: <UpdateMyPage />,
},
],
},

{
path: "/test",
element: <TestPage />,
Expand Down