Skip to content

Commit f678253

Browse files
committed
feat: 방 목록, 방 생성, 방 입장 구현
1 parent 9bd4f80 commit f678253

File tree

4 files changed

+82
-350
lines changed

4 files changed

+82
-350
lines changed

src/pages/room/CreateRoomModal.js

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
import { useState } from "react"
44
import styles from "./room.module.scss"
55

6-
const CreateRoomModal = ({ isOpen, onClose }) => {
7-
const [title, setTitle] = useState("")
8-
const [personCount, setPersonCount] = useState("2")
9-
const [isSecret, setSecret] = useState(false)
6+
const CreateRoomModal = ({ isOpen, onClose, onSubmit }) => {
7+
const [roomName, setRoomName] = useState("")
8+
const [maxUserCount, setMaxUserCount] = useState("2")
9+
const [locked, setLocked] = useState(false)
1010
const [password, setPassword] = useState("")
1111

1212
const handlePasswordChange = (e) => {
@@ -15,16 +15,17 @@ const CreateRoomModal = ({ isOpen, onClose }) => {
1515

1616
const handleIsSecretChange = (e) => {
1717
const checked = e.target.checked
18-
setSecret(checked)
18+
setLocked(checked)
1919
if (!checked) {
2020
setPassword("")
2121
}
2222
}
2323

2424
const handleSubmit = () => {
2525
// 방 생성 로직
26-
console.log("방 생성:", { title, personCount, isSecret, password })
27-
onClose()
26+
console.log("방 생성:", { roomName, maxUserCount, locked, password })
27+
onSubmit({ roomName, maxUserCount, locked, password });
28+
onClose();
2829
}
2930

3031
const handleOverlayClick = (e) => {
@@ -54,8 +55,8 @@ const CreateRoomModal = ({ isOpen, onClose }) => {
5455
id="roomTitle"
5556
type="text"
5657
className={styles.formInput}
57-
value={title}
58-
onChange={(e) => setTitle(e.target.value)}
58+
value={roomName}
59+
onChange={(e) => setRoomName(e.target.value)}
5960
placeholder="방 제목을 입력하세요"
6061
/>
6162
</div>
@@ -67,8 +68,8 @@ const CreateRoomModal = ({ isOpen, onClose }) => {
6768
<select
6869
id="personCount"
6970
className={styles.formSelect}
70-
value={personCount}
71-
onChange={(e) => setPersonCount(e.target.value)}
71+
value={maxUserCount}
72+
onChange={(e) => setMaxUserCount(e.target.value)}
7273
>
7374
<option value="2">2명</option>
7475
<option value="3">3명</option>
@@ -85,7 +86,7 @@ const CreateRoomModal = ({ isOpen, onClose }) => {
8586
id="usePassword"
8687
type="checkbox"
8788
className={styles.checkbox}
88-
checked={isSecret}
89+
checked={locked}
8990
onChange={handleIsSecretChange}
9091
/>
9192
<label className={styles.checkboxLabel} htmlFor="usePassword">
@@ -103,8 +104,8 @@ const CreateRoomModal = ({ isOpen, onClose }) => {
103104
className={styles.formInput}
104105
value={password}
105106
onChange={handlePasswordChange}
106-
disabled={!isSecret}
107-
placeholder={isSecret ? "비밀번호를 입력하세요" : "비밀번호 사용을 체크해주세요"}
107+
disabled={!locked}
108+
placeholder={locked ? "비밀번호를 입력하세요" : "비밀번호 사용을 체크해주세요"}
108109
/>
109110
</div>
110111
</div>

src/pages/room/RoomCard.js

Lines changed: 6 additions & 188 deletions
Original file line numberDiff line numberDiff line change
@@ -1,192 +1,10 @@
1-
// import React, { useState } from 'react';
2-
3-
// const roomCardList = [
4-
// { id: 1, isSecret: false, isPlay: false, title: '겜할 사람 급구 ㄱ', totalPerson: 8, currentPerson: 4 },
5-
// { id: 2, isSecret: true, isPlay: true, title: '용호초로 나온나', totalPerson: 8, currentPerson: 8 },
6-
// { id: 3, isSecret: false, isPlay: false, title: '친친만', totalPerson: 2, currentPerson: 2 },
7-
// { id: 4, isSecret: true, isPlay: false, title: '놀 사람', totalPerson: 8, currentPerson: 4 },
8-
// ];
9-
10-
// const RoomCard = ({ room }) => {
11-
// const isFullRoom = room.currentPerson >= room.totalPerson;
12-
// const participationRate = (room.currentPerson / room.totalPerson) * 100;
13-
14-
// return (
15-
// <div className="bg-white rounded-xl shadow-lg hover:shadow-xl transition-all duration-300 overflow-hidden border border-gray-200 hover:border-red-300">
16-
// {/* Header with status indicators */}
17-
// <div className="bg-gradient-to-r from-gray-800 to-gray-900 p-4 relative">
18-
// <div className="absolute top-3 right-3 flex gap-2">
19-
// {room.isSecret && (
20-
// <span className="text-yellow-400 text-lg">🔒</span>
21-
// )}
22-
// {room.isPlay && (
23-
// <span className="text-green-400 text-lg animate-pulse">▶️</span>
24-
// )}
25-
// </div>
26-
27-
// <h3 className="text-white font-bold text-lg mb-2 pr-16">
28-
// {room.title}
29-
// </h3>
30-
31-
// {/* Participants info */}
32-
// <div className="flex items-center justify-between">
33-
// <div className="flex items-center gap-2 text-gray-300">
34-
// <span className="text-red-400">👥</span>
35-
// <span className="font-semibold text-white">{room.currentPerson}</span>
36-
// <span className="text-gray-400">/</span>
37-
// <span className="text-gray-400">{room.totalPerson}</span>
38-
// </div>
39-
// <div className={`px-2 py-1 rounded-lg text-xs font-medium ${
40-
// isFullRoom
41-
// ? 'bg-red-500/20 text-red-400'
42-
// : room.isPlay
43-
// ? 'bg-green-500/20 text-green-400'
44-
// : 'bg-blue-500/20 text-blue-400'
45-
// }`}>
46-
// {isFullRoom ? 'FULL' : room.isPlay ? 'RACING' : 'WAITING'}
47-
// </div>
48-
// </div>
49-
// </div>
50-
51-
// {/* Body */}
52-
// <div className="p-4">
53-
// {/* Progress bar */}
54-
// <div className="mb-4">
55-
// <div className="w-full bg-gray-200 rounded-full h-2 overflow-hidden">
56-
// <div
57-
// className={`h-full rounded-full transition-all duration-500 ${
58-
// isFullRoom
59-
// ? 'bg-gradient-to-r from-red-500 to-red-600'
60-
// : 'bg-gradient-to-r from-blue-500 to-red-500'
61-
// }`}
62-
// style={{ width: `${participationRate}%` }}
63-
// ></div>
64-
// </div>
65-
// </div>
66-
67-
// {/* Join button */}
68-
// <button
69-
// className={`w-full py-3 px-4 rounded-lg font-bold transition-all duration-300 ${
70-
// isFullRoom
71-
// ? 'bg-gray-300 text-gray-500 cursor-not-allowed'
72-
// : 'bg-gradient-to-r from-red-600 to-red-700 hover:from-red-500 hover:to-red-600 text-white transform hover:scale-105 shadow-lg hover:shadow-red-500/30'
73-
// }`}
74-
// disabled={isFullRoom}
75-
// >
76-
// {isFullRoom ? 'ROOM FULL' : 'JOIN RACE'}
77-
// </button>
78-
// </div>
79-
// </div>
80-
// );
81-
// };
82-
83-
// const CreateRoomModal = ({ isOpen, onClose }) => {
84-
// if (!isOpen) return null;
85-
86-
// return (
87-
// <div className="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50">
88-
// <div className="bg-white rounded-xl p-8 max-w-md w-full mx-4 shadow-2xl">
89-
// <div className="flex justify-between items-center mb-6">
90-
// <h2 className="text-2xl font-bold text-gray-800">Create New Room</h2>
91-
// <button
92-
// onClick={onClose}
93-
// className="text-gray-400 hover:text-gray-600 text-2xl"
94-
// >
95-
// ×
96-
// </button>
97-
// </div>
98-
// <div className="space-y-4">
99-
// <input
100-
// type="text"
101-
// placeholder="Room Title"
102-
// className="w-full bg-gray-50 text-gray-800 rounded-lg px-4 py-3 border border-gray-300 focus:border-red-500 focus:outline-none focus:ring-2 focus:ring-red-500/20"
103-
// />
104-
// <button className="w-full bg-gradient-to-r from-red-600 to-red-700 hover:from-red-500 hover:to-red-600 text-white font-bold py-3 rounded-lg transition-all duration-300">
105-
// CREATE ROOM
106-
// </button>
107-
// </div>
108-
// </div>
109-
// </div>
110-
// );
111-
// };
112-
113-
// const RoomList = () => {
114-
// const [keyword, setKeyword] = useState("");
115-
// const [createRoomModalOpen, setCreateRoomModalOpen] = useState(false);
116-
117-
// const handleSearchClick = (e) => {
118-
// console.log("🔍 검색 버튼 클릭됨");
119-
// e.preventDefault();
120-
// e.stopPropagation();
121-
// };
122-
123-
// const handleKeyDown = (e) => {
124-
// if (e.key === "Enter") {
125-
// console.log("🔍 엔터키 눌림");
126-
// handleSearchClick(e);
127-
// }
128-
// };
129-
130-
// return (
131-
// <div className="min-h-screen bg-gray-100">
132-
// {/* Header */}
133-
// <div className="bg-gradient-to-r from-red-600 to-red-700 text-white py-8">
134-
// <div className="container mx-auto px-4 text-center">
135-
// <h1 className="text-4xl font-bold mb-2">
136-
// RACING LOBBY
137-
// </h1>
138-
// <p className="text-red-100 text-lg">Join the ultimate racing experience</p>
139-
// </div>
140-
// </div>
141-
142-
// <div className="container mx-auto px-4 py-8">
143-
// {/* Search and Create Section */}
144-
// <div className="flex flex-col md:flex-row gap-4 justify-center items-center mb-8">
145-
// <div className="relative">
146-
// <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
147-
// <span className="text-gray-400">🔍</span>
148-
// </div>
149-
// <input
150-
// type="text"
151-
// placeholder="Search rooms..."
152-
// value={keyword}
153-
// onChange={(e) => setKeyword(e.target.value)}
154-
// onKeyDown={handleKeyDown}
155-
// className="w-80 bg-white border border-gray-300 rounded-lg py-3 pl-10 pr-4 text-gray-900 focus:outline-none focus:ring-2 focus:ring-red-500 focus:border-transparent"
156-
// />
157-
// </div>
158-
159-
// <button
160-
// onClick={() => setCreateRoomModalOpen(true)}
161-
// className="flex items-center gap-2 bg-gradient-to-r from-red-600 to-red-700 hover:from-red-500 hover:to-red-600 text-white font-bold py-3 px-6 rounded-lg transition-all duration-300 transform hover:scale-105"
162-
// >
163-
// <span>➕</span>
164-
// CREATE NEW ROOM
165-
// </button>
166-
// </div>
167-
168-
// {/* Room Grid - 2x2 layout */}
169-
// <div className="grid grid-cols-1 md:grid-cols-2 gap-6 max-w-4xl mx-auto">
170-
// {roomCardList.map((room) => (
171-
// <RoomCard key={room.id} room={room} />
172-
// ))}
173-
// </div>
174-
// </div>
175-
176-
// <CreateRoomModal isOpen={createRoomModalOpen} onClose={() => setCreateRoomModalOpen(false)} />
177-
// </div>
178-
// );
179-
// };
180-
181-
// export default RoomList;
182-
1831

1842
import React from 'react';
1853
import styles from './room.module.scss';
1864

1875
const RoomCard = ({ room, onEnterRoom }) => {
188-
const isFullRoom = room.currentPlayers >= room.maxPlayers;
189-
const isPrivate = room.isPrivate;
6+
const isFullRoom = room.currentUserCount >= room.maxUserCount;
7+
const isPrivate = room.locked;
1908

1919
const handleEnterRoom = () => {
19210
if (!isFullRoom && onEnterRoom) {
@@ -197,10 +15,10 @@ const RoomCard = ({ room, onEnterRoom }) => {
19715
return (
19816
<div className={styles.quizCard} onClick={handleEnterRoom}>
19917
<div className={styles.hoverCard}>
200-
<h3>{room.title}</h3>
18+
<h3>{room.roomName}</h3>
20119
<p>{room.description}</p>
20220
<p>제작자: {room.creator}</p>
203-
<p>총 문제: {room.questionCount} 문제</p>
21+
<p>총 문제: {room.numberOfQuestions} 문제</p>
20422
</div>
20523

20624
<div className={styles.quizThumbnail}>
@@ -209,14 +27,14 @@ const RoomCard = ({ room, onEnterRoom }) => {
20927
🔒 비밀방
21028
</div>
21129
)}
212-
<img src={room.thumbnail} alt="Quiz Thumbnail" />
30+
<img src={room.thumbnailUrl} alt="Quiz Thumbnail" />
21331
</div>
21432

21533
<div className={styles.quizInfo}>
21634
<h3 className={styles.quizTitle}>{room.title}</h3>
21735
<div className={styles.quizStats}>
21836
<span className={`${styles.quizParticipants} ${isFullRoom ? styles.full : ''}`}>
219-
인원: {room.currentPlayers} / {room.maxPlayers}
37+
인원: {room.currentUserCount} / {room.maxUserCount}
22038
</span>
22139
<button
22240
className={styles.quizStatus}

0 commit comments

Comments
 (0)