Skip to content

Commit

Permalink
Merge pull request #165 from ijun17/feature-fe-#15#16#31#41#162
Browse files Browse the repository at this point in the history
[FE] feat#15#16#31#41#162 ν”Œλ ˆμ΄μ–΄ λ‹‰λ„€μž„ μž…λ ₯μ°½ 및 κ²Œμž„ λŒ€κΈ°λ°© λ ˆμ΄μ•„μ›ƒ 개발
  • Loading branch information
ijun17 authored Nov 6, 2024
2 parents f637f85 + eaece19 commit 7d322ff
Show file tree
Hide file tree
Showing 22 changed files with 591 additions and 58 deletions.
11 changes: 4 additions & 7 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
- 제λͺ© : feat(issue 번호): κΈ°λŠ₯λͺ…
ex) feat(17): pull request template μž‘μ„±
- 제λͺ© : [BE/FE] feat#이슈번호 κΈ°λŠ₯λͺ…
ex) [BE] feat#156 μžλ™λ°°ν¬ κ΅¬ν˜„
(확인 ν›„ μ§€μ›Œμ£Όμ„Έμš”)

β–² PR 제λͺ© κ΄€λ ¨ μΆ”κ°€ λ…Όμ˜ ν›„ μˆ˜μ •

## βž• 이슈 번호

- #이슈번호
Expand All @@ -22,14 +20,13 @@

<br/>



## 🎯 리뷰 μš”κ΅¬μ‚¬ν•­
## 🎯 리뷰 μš”κ΅¬μ‚¬ν•­ (선택)

- νŠΉλ³„νžˆ 봐쀬으면 ν•˜λŠ” 뢀뢄이 μžˆλ‹€λ©΄ μ μ–΄μ£Όμ„Έμš”

<br/>

## βœ… Check List

- [ ] mergeν•  브랜치의 μœ„μΉ˜λ₯Ό ν™•μΈν–ˆλ‚˜μš”?
- [ ] Label을 μ§€μ •ν–ˆλ‚˜μš”?
86 changes: 86 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Deploy To EC2

on:
push:
branches:
- main

jobs:
deploy:
runs-on: ubuntu-latest
# defaults:
# run:
# working-directory: ./BE # BE 디렉토리λ₯Ό μž‘μ—… λ””λ ‰ν† λ¦¬λ‘œ μ„€μ •

steps:
- name: Github Repository 파일 뢈러였기
uses: actions/checkout@v4

- name: Node μ„€μΉ˜
uses: actions/setup-node@v4
with:
node-version: "20"

- name: BE μ˜μ‘΄μ„± μ„€μΉ˜
working-directory: ./BE
run: npm ci

- name: FE μ˜μ‘΄μ„± μ„€μΉ˜
working-directory: ./FE
run: npm ci

- name: .env 파일 λ§Œλ“€κΈ°
run: |
echo '${{ secrets.ENV }}' > .env
- name: ν…ŒμŠ€νŠΈ μ½”λ“œ μ‹€ν–‰
run: npm run test

- name: λΉŒλ“œ
run: npm run build

- name: github-action μ»΄ν“¨ν„°μ—μ„œ μ••μΆ•ν•˜κΈ°
run: |
# ν˜„μž¬ μœ„μΉ˜ 확인 (λ””λ²„κΉ…μš©)
pwd
# BE와 FE λͺ¨λ“  ν•„μš” νŒŒμΌλ“€μ„ ν•¨κ»˜ μ••μΆ•
tar -czvf project.tar.gz \
BE/dist \
BE/package.json \
BE/package-lock.json \
BE/.env \
FE/build \
FE/package.json \
FE/package-lock.json \
FE/.env
# μ••μΆ• 파일 λ‚΄μš© 확인 (λ””λ²„κΉ…μš©)
echo "Created archive with contents:"
tar -tvf project.tar.gz
- name: SCP둜 EC2에 λΉŒλ“œλœ 파일 μ „μ†‘ν•˜κΈ°
uses: appleboy/[email protected]
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_PRIVATE_KEY }}
source: project.tar.gz
target: /root/nest-server/tobe

- name: SSH둜 EC2에 μ ‘μ†ν•˜κΈ°
uses: appleboy/[email protected]
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_PRIVATE_KEY }}
script_stop: true
script: |
rm -rf /root/nest-server/current
mkdir /root/nest-server/current
mv /root/nest-server/tobe/project.tar.gz /root/nest-server/current/project.tar.gz
cd /root/nest-server/current
tar -xvf project.tar.gz
npm i
pm2 kill
pm2 start dist/main.js --name "backend-server"
18 changes: 18 additions & 0 deletions FE/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions FE/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
},
"devDependencies": {
"@eslint/js": "^9.13.0",
"@types/node": "^22.9.0",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@vitejs/plugin-react": "^4.3.3",
Expand Down
2 changes: 2 additions & 0 deletions FE/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import { MainPage } from './pages/MainPage';
import { GameSetupPage } from './pages/GameSetupPage';
import { GamePage } from './pages/GamePage';

function App() {
return (
<Router>
<Routes>
<Route path="/" element={<MainPage />} />
<Route path="/game/setup" element={<GameSetupPage />} />
<Route path="/game/:id" element={<GamePage />} />
<Route path="*" element={<div>not found</div>} />
</Routes>
</Router>
Expand Down
42 changes: 25 additions & 17 deletions FE/src/api/socket.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import { io, Socket } from 'socket.io-client';
import SocketEvents from '../constants/socketEvents';

type SocketEvent = (typeof SocketEvents)[keyof typeof SocketEvents];
// type SocketEvent = (typeof SocketEvents)[keyof typeof SocketEvents];

interface ChatMessage {
type ChatMessage = {
userId: string;
message: string;
}
};

interface CreateRoomPayload {
roomName: string;
maxPlayers: number;
type CreateRoomPayload = {
title: string;
maxPlayerCount: number;
gameMode: string;
isPublic: boolean;
}
};

// 이벀트의 데이터 νƒ€μž…μ„ μ •μ˜
interface SocketDataMap {
chatMessage: ChatMessage;
createRoom: CreateRoomPayload;
// λ‹€λ₯Έ 이벀트의 데이터 νƒ€μž…μ„ μΆ”κ°€
}
// type SocketDataMap = {
// [SocketEvents.CHAT_MESSAGE]: ChatMessage;
// [SocketEvents.CREATE_ROOM]: CreateRoomPayload;
// // λ‹€λ₯Έ 이벀트의 데이터 νƒ€μž…μ„ μΆ”κ°€
// };

class SocketService {
private socket: Socket;
Expand All @@ -44,11 +44,11 @@ class SocketService {
}

// 이벀트 μˆ˜μ‹  λ©”μ„œλ“œ
on<T extends SocketEvent>(event: T, callback: (data: SocketDataMap[T]) => void) {
this.socket.on(event, (data: SocketDataMap[T]) => {
callback(data);
});
}
// on<T extends SocketEvent>(event: T, callback: (data: SocketDataMap[T]) => void) {
// this.socket.on(event, (data: SocketDataMap[T]) => {
// callback(data);
// });
// }

// λ©”μ‹œμ§€ 전솑 λ©”μ„œλ“œ
sendChatMessage(message: ChatMessage) {
Expand All @@ -65,6 +65,14 @@ class SocketService {
disconnect() {
this.socket.disconnect();
}

joinRoom(gameId: string, playerName: string) {
this.socket.send(SocketEvents.JOIN_ROOM, { gameId, playerName });
}

chatMessage(gameId: string, message: string) {
this.socket.send(SocketEvents.CHAT_MESSAGE, { gameId, message });
}
}

export const socketService = new SocketService('');
61 changes: 61 additions & 0 deletions FE/src/components/Chat.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { socketService } from '@/api/socket';
import { useEffect, useState } from 'react';

const sampleChat = Array(100)
.fill(null)
.map((_, i) => ({ name: 'user' + i, message: 'messagemessagemessagemessagemessagemessage' }));

const Chat = () => {
const [messages, setMessages] = useState<Array<{ name: string; message: string }>>([]);
const [inputValue, setInputValue] = useState('');

useEffect(() => {
setMessages(sampleChat); //TODO λ‚˜μ€‘μ— 고쳐야 함
// μ„œλ²„μ—μ„œ λ©”μ‹œμ§€λ₯Ό 받을 λ•Œ
// socket.on('chat message', (message) => {
// setMessages((prevMessages) => [...prevMessages, message]);
// });
// return () => {
// socket.off('chat message');
// };
}, []);

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

const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();

if (inputValue.trim()) {
socketService.chatMessage('1234', inputValue);
setInputValue('');
}
};
return (
<div className="component-default h-[100%]">
<div className="border-b border-default center h-[2.5rem]">λ©”μ‹œμ§€</div>
<div className="p-2 h-[calc(100%-6rem)] overflow-y-scroll">
{messages.map((e, i) => (
<div className="break-words leading-5 mt-3" key={i}>
<span className="font-bold mr-2">{e.name}</span>
<span>{e.message}</span>
</div>
))}
</div>
<div className="center border-t border-default h-[3.5rem] p-2">
<form onSubmit={handleSubmit} className="w-full h-full">
<input
className="bg-[#0001] w-[100%] h-[100%] rounded-m p-2"
type="text"
placeholder="λ©”μ‹œμ§€"
value={inputValue}
onChange={handleInputChange}
/>
</form>
</div>
</div>
);
};

export default Chat;
26 changes: 26 additions & 0 deletions FE/src/components/ClipboardCopy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Button } from '@mui/material';

type ClipboardCopyProps = {
valueToCopy: string;
message: string;
className?: string;
};

export const ClipboardCopy: React.FC<ClipboardCopyProps> = ({ valueToCopy, message }) => {
const handleCopyToClipboard = (): void => {
navigator.clipboard
.writeText(valueToCopy)
.then(() => {
alert('ν΄λ¦½λ³΄λ“œμ— λ³΅μ‚¬λ˜μ—ˆμŠ΅λ‹ˆλ‹€: ');
})
.catch((err) => {
console.error('볡사 μ‹€νŒ¨:', err);
});
};

return (
<div>
<Button onClick={handleCopyToClipboard}>{message}</Button>
</div>
);
};
29 changes: 29 additions & 0 deletions FE/src/components/GameHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { ClipboardCopy } from './ClipboardCopy';
import Card from '@mui/material/Card';
import { QuizPreview } from './QuizView';

export const GameHeader = () => {
// μž„μ‹œκ°’
const pinNum = '123456';
const linkURL = 'naver.com';
return (
<Card className="p-4 border border-blue-600 shadow-xl rounded-md h-[280px] w-[1000px] bg-gradient-to-b from-blue-500 to-blue-700 text-white">
<div className="flex justify-center mb-4">
<ClipboardCopy valueToCopy={pinNum} message={`PIN: ${pinNum} 볡사`} />
<ClipboardCopy valueToCopy={linkURL} message="곡유 링크 볡사" />
</div>
<div className="flex flex-col items-center justify-center text-center space-y-2">
<span className="text-xl font-semibold">ν€΄μ¦ˆμ΄λ¦„22</span>
</div>
<QuizPreview title="title" description="ν€΄μ¦ˆν€΄μ¦ˆν€΄γ…£μ¦ˆ" />
<div className="flex space-x-4 justify-center">
<button className="bg-yellow-400 text-black font-bold py-2 px-4 rounded-md shadow-lg transform hover:translate-y-[-2px] hover:shadow-xl active:translate-y-1 active:shadow-sm transition">
ν€΄μ¦ˆ μ„€μ •
</button>
<button className="bg-blue-500 text-white font-bold py-2 px-4 rounded-md shadow-lg transform hover:translate-y-[-2px] hover:shadow-xl active:translate-y-1 active:shadow-sm transition">
κ²Œμž„ μ‹œμž‘
</button>
</div>
</Card>
);
};
7 changes: 7 additions & 0 deletions FE/src/components/HeaderBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const HeaderBar = () => {
return (
<header className="h-[100px] text-l leading-[100px] pl-8 font-bold bg-main text-white">
QuizGround
</header>
);
};
Loading

0 comments on commit 7d322ff

Please sign in to comment.