-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #167 from boostcampwm-2024/dev-fe
[FE] λ°°ν¬ ν μ€νΈ
- Loading branch information
Showing
26 changed files
with
1,295 additions
and
121 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,19 @@ | ||
import { useState } from 'react' | ||
import reactLogo from './assets/react.svg' | ||
import viteLogo from '/vite.svg' | ||
import './App.css' | ||
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() { | ||
const [count, setCount] = useState(0) | ||
|
||
return ( | ||
<> | ||
<div> | ||
<a href="https://vite.dev" target="_blank"> | ||
<img src={viteLogo} className="logo" alt="Vite logo" /> | ||
</a> | ||
<a href="https://react.dev" target="_blank"> | ||
<img src={reactLogo} className="logo react" alt="React logo" /> | ||
</a> | ||
</div> | ||
<h1>Vite + React</h1> | ||
<div className="card"> | ||
<button onClick={() => setCount((count) => count + 1)}> | ||
count is {count} | ||
</button> | ||
<p> | ||
Edit <code>src/App.tsx</code> and save to test HMR | ||
</p> | ||
</div> | ||
<p className="read-the-docs"> | ||
Click on the Vite and React logos to learn more | ||
</p> | ||
</> | ||
) | ||
<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> | ||
); | ||
} | ||
|
||
export default App | ||
export default App; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { io, Socket } from 'socket.io-client'; | ||
import SocketEvents from '../constants/socketEvents'; | ||
|
||
// type SocketEvent = (typeof SocketEvents)[keyof typeof SocketEvents]; | ||
|
||
type ChatMessage = { | ||
userId: string; | ||
message: string; | ||
}; | ||
|
||
type CreateRoomPayload = { | ||
title: string; | ||
maxPlayerCount: number; | ||
gameMode: string; | ||
isPublic: boolean; | ||
}; | ||
|
||
// μ΄λ²€νΈμ λ°μ΄ν° νμ μ μ μ | ||
// type SocketDataMap = { | ||
// [SocketEvents.CHAT_MESSAGE]: ChatMessage; | ||
// [SocketEvents.CREATE_ROOM]: CreateRoomPayload; | ||
// // λ€λ₯Έ μ΄λ²€νΈμ λ°μ΄ν° νμ μ μΆκ° | ||
// }; | ||
|
||
class SocketService { | ||
private socket: Socket; | ||
private url: string; | ||
|
||
constructor(url: string) { | ||
this.socket = io(); | ||
this.url = url; | ||
} | ||
|
||
connect() { | ||
this.socket = io(this.url); | ||
return new Promise((resolve, reject) => { | ||
this.socket.on('connect', () => resolve(null)); | ||
this.socket.on('error', () => reject()); | ||
}); | ||
} | ||
|
||
isActive() { | ||
return this.socket && this.socket.active; | ||
} | ||
|
||
// μ΄λ²€νΈ μμ λ©μλ | ||
// on<T extends SocketEvent>(event: T, callback: (data: SocketDataMap[T]) => void) { | ||
// this.socket.on(event, (data: SocketDataMap[T]) => { | ||
// callback(data); | ||
// }); | ||
// } | ||
|
||
// λ©μμ§ μ μ‘ λ©μλ | ||
sendChatMessage(message: ChatMessage) { | ||
this.socket.emit(SocketEvents.CHAT_MESSAGE, message); | ||
} | ||
|
||
// λ°© μμ± λ©μλ | ||
async createRoom(payload: CreateRoomPayload) { | ||
await this.connect(); | ||
this.socket.emit(SocketEvents.CREATE_ROOM, payload); | ||
} | ||
|
||
// μ°κ²° μ’ λ£ λ©μλ | ||
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('http://quizground.duckdns.org:3000/game'); |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import React, { useState } from 'react'; | ||
|
||
type ModalProps = { | ||
isOpen: boolean; | ||
title: string; | ||
placeholder?: string; | ||
initialValue?: string; | ||
onClose: () => void; | ||
onSubmit: (value: string) => void; | ||
}; | ||
|
||
export const Modal: React.FC<ModalProps> = ({ | ||
isOpen, | ||
title, | ||
placeholder, | ||
initialValue = '', | ||
onClose, | ||
onSubmit | ||
}) => { | ||
const [inputValue, setInputValue] = useState(initialValue); | ||
|
||
if (!isOpen) return null; | ||
|
||
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { | ||
setInputValue(e.target.value); | ||
}; | ||
|
||
const handleSubmit = () => { | ||
onSubmit(inputValue); | ||
setInputValue(''); // μ λ ₯κ° μ΄κΈ°ν | ||
}; | ||
|
||
return ( | ||
<div className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50"> | ||
<div className="bg-white rounded-lg shadow-lg p-6 max-w-sm w-full"> | ||
<h2 className="text-xl font-semibold mb-4">{title}</h2> | ||
<input | ||
type="text" | ||
placeholder={placeholder} | ||
value={inputValue} | ||
onChange={handleInputChange} | ||
className="border border-gray-300 rounded-md p-2 mb-4 w-full" | ||
/> | ||
<div className="flex justify-end"> | ||
<button | ||
onClick={handleSubmit} | ||
className="bg-blue-500 text-white rounded-md px-4 py-2 mr-2 hover:bg-blue-600" | ||
> | ||
λ±λ‘ | ||
</button> | ||
{/* λλ€μ λ±λ‘ λͺ¨λ¬μμ μ·¨μλ²νΌμ μμ΄μΌν κ²κ°μλ° μΌλ¨ λ£μ΄λ */} | ||
<button | ||
onClick={onClose} | ||
className="bg-gray-300 text-gray-700 rounded-md px-4 py-2 hover:bg-gray-400" | ||
> | ||
μ·¨μ | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
}; |
Oops, something went wrong.