๐ŸŽฏ ํ€ด์ฆˆ ๋ฐฐํ‹€ ์•„๋ ˆ๋‚˜ - ์นœ๊ตฌ์™€ ์‹ค์‹œ๊ฐ„ ๋Œ€๊ฒฐํ•˜๋Š” ํ€ด์ฆˆ ๊ฒŒ์ž„ - ๋ฐ”์ด๋ธŒ์ฝ”๋”ฉ ๋ ˆ์‹œํ”ผ
์ž…๋ฌธ PHP + JavaScript Laravel + React AI: Claude

๐ŸŽฏ ํ€ด์ฆˆ ๋ฐฐํ‹€ ์•„๋ ˆ๋‚˜ - ์นœ๊ตฌ์™€ ์‹ค์‹œ๊ฐ„ ๋Œ€๊ฒฐํ•˜๋Š” ํ€ด์ฆˆ ๊ฒŒ์ž„

๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ช… quiz-battle-arena-fullstack
์กฐํšŒ์ˆ˜ 131 0๊ฑด ์ œ์ถœ

๋ฌธ์ œ ์„ค๋ช…

๐ŸŽฎ ํ”„๋กœ์ ํŠธ ๊ฐœ์š”

์นœ๊ตฌ๋“ค๊ณผ ํ•จ๊ป˜ ์ฆ๊ธฐ๋Š” ์‹ค์‹œ๊ฐ„ ํ€ด์ฆˆ ๋Œ€๊ฒฐ ํ”Œ๋žซํผ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค! ์‚ฌ์šฉ์ž๋Š” ๋‹ค์–‘ํ•œ ์นดํ…Œ๊ณ ๋ฆฌ(์˜ํ™”, ์Œ์•…, ์Šคํฌ์ธ , ๊ณผํ•™ ๋“ฑ)์˜ ํ€ด์ฆˆ ๋ฐฉ์„ ์ƒ์„ฑํ•˜๊ณ , ์นœ๊ตฌ๋ฅผ ์ดˆ๋Œ€ํ•˜์—ฌ ๋ˆ„๊ฐ€ ๋” ๋งŽ์€ ๋ฌธ์ œ๋ฅผ ๋งžํžˆ๋Š”์ง€ ๊ฒฝ์Ÿํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

โœจ ํ•„์ˆ˜ ๊ธฐ๋Šฅ

  1. ํ€ด์ฆˆ ๋ฐฉ ์ƒ์„ฑ: ์นดํ…Œ๊ณ ๋ฆฌ ์„ ํƒ, ๋ฌธ์ œ ๊ฐœ์ˆ˜ ์„ค์ •, ๋ฐฉ ์ œ๋ชฉ ์ž…๋ ฅ
  2. ํ€ด์ฆˆ ๋ชฉ๋ก ํŽ˜์ด์ง€: ํ˜„์žฌ ์ง„ํ–‰ ์ค‘์ธ ํ€ด์ฆˆ ๋ฐฉ ๋ชฉ๋ก (์นด๋“œ ํ˜•ํƒœ๋กœ ํ‘œ์‹œ)
  3. ํ€ด์ฆˆ ํ”Œ๋ ˆ์ด ํŽ˜์ด์ง€: ๋ฌธ์ œ ํ‘œ์‹œ, 4๊ฐœ์˜ ์„ ํƒ์ง€, ํƒ€์ด๋จธ(30์ดˆ), ์ •๋‹ต/์˜ค๋‹ต ํ”ผ๋“œ๋ฐฑ
  4. ์ ์ˆ˜ ์ง‘๊ณ„: ๋งžํžŒ ๋ฌธ์ œ ๊ฐœ์ˆ˜, ์ •๋‹ต๋ฅ , ์†Œ์š” ์‹œ๊ฐ„ ๊ธฐ๋ก
  5. ๊ฒฐ๊ณผ ํŽ˜์ด์ง€: ์ตœ์ข… ์ ์ˆ˜, ์ˆœ์œ„, ์ •๋‹ต ํ™•์ธ

๐ŸŽ ๋ณด๋„ˆ์Šค ๊ธฐ๋Šฅ

  • ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ๋‚œ์ด๋„ ์กฐ์ ˆ (์‰ฌ์›€/๋ณดํ†ต/์–ด๋ ค์›€)
  • ์—ฐ์† ์ •๋‹ต ์ฝค๋ณด ์‹œ์Šคํ…œ (3์—ฐ์† ์ •๋‹ต ์‹œ ๋ณด๋„ˆ์Šค ์ ์ˆ˜)
  • ํ€ด์ฆˆ ํžˆ์Šคํ† ๋ฆฌ (๋‚ด๊ฐ€ ์ฐธ์—ฌํ•œ ํ€ด์ฆˆ ๊ธฐ๋ก)
  • ๋ฆฌ๋”๋ณด๋“œ (์ „์ฒด ์‚ฌ์šฉ์ž ์ค‘ ์ตœ๊ณ  ์ ์ˆ˜)
  • ๊ณต์œ  ๊ธฐ๋Šฅ (๊ฒฐ๊ณผ๋ฅผ SNS์— ๊ณต์œ )

๐ŸŽจ ๋””์ž์ธ ํฌ์ธํŠธ

  • ๊ฒŒ์ž„๋‹ค์šด ์ƒ๋™๊ฐ ์žˆ๋Š” UI (๋ฒ„ํŠผ ํ˜ธ๋ฒ„ ์• ๋‹ˆ๋ฉ”์ด์…˜, ์ •๋‹ต ์‹œ ์ถ•ํ•˜ ํšจ๊ณผ)
  • ํƒ€์ด๋จธ ์ง„ํ–‰๋ฐ” (์‹œ๊ฐ„์ด ์ค„์–ด๋“ค์ˆ˜๋ก ์ƒ‰์ƒ ๋ณ€ํ™”)
  • ์นด๋“œ ํ”Œ๋ฆฝ ์• ๋‹ˆ๋ฉ”์ด์…˜ (๋ฌธ์ œ ์ „ํ™˜ ์‹œ)
  • ๋ฐ˜์‘ํ˜• ๋””์ž์ธ (๋ชจ๋ฐ”์ผ์—์„œ๋„ ์พŒ์ ํ•˜๊ฒŒ)

๐Ÿ›  ๊ธฐ์ˆ  ์Šคํƒ

  • ๋ฐฑ์—”๋“œ: Laravel 13.x (RESTful API)
  • ํ”„๋ก ํŠธ์—”๋“œ: React 19 (Vite)
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค: SQLite
  • ์Šคํƒ€์ผ๋ง: Tailwind CSS

์ œ์•ฝ ์กฐ๊ฑด

  • โ€ข Laravel 13.x ์ตœ์‹  ๋ฒ„์ „ ์‚ฌ์šฉ ํ•„์ˆ˜
  • โ€ข React 19 ์ตœ์‹  ๋ฒ„์ „ ์‚ฌ์šฉ ํ•„์ˆ˜
  • โ€ข ๋ฐฑ์—”๋“œ๋Š” RESTful API ์„œ๋ฒ„๋กœ ๊ตฌ์„ฑ (Laravel API)
  • โ€ข ํ”„๋ก ํŠธ์—”๋“œ๋Š” Vite ๊ธฐ๋ฐ˜ React ํ”„๋กœ์ ํŠธ๋กœ ๋ณ„๋„ ๊ตฌ์„ฑ
  • โ€ข fetch ๋˜๋Š” axios๋กœ API ํ˜ธ์ถœํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์—ฐ๋™
  • โ€ข SQLite ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‚ฌ์šฉ (๊ฐ„๋‹จํ•œ ์„ค์ •)
  • โ€ข Tailwind CSS๋กœ ์Šคํƒ€์ผ๋ง
  • โ€ข ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ…/WebSocket ๊ธฐ๋Šฅ ๊ธˆ์ง€ (HTTP ๊ธฐ๋ฐ˜ ํ†ต์‹ ๋งŒ ์‚ฌ์šฉ)
  • โ€ข ๋ณต์žกํ•œ ์ƒํƒœ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ ๊ธˆ์ง€ (useState๋งŒ ์‚ฌ์šฉ)
  • โ€ข Git ์ปค๋ฐ‹์€ ๊ฐ ๋‹จ๊ณ„๋งˆ๋‹ค ์ˆ˜ํ–‰

ํ”„๋กฌํ”„ํŠธ ๋ ˆ์‹œํ”ผ

์•„๋ž˜ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ AI์—๊ฒŒ ๋ณด๋‚ด๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๋ณต์‚ฌ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ๋ฐ”๋กœ ์‚ฌ์šฉํ•˜์„ธ์š”.

1
Step 1
mkdir quiz-battle-arena-fullstack && cd quiz-battle-arena-fullstack

์ด ํด๋”์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

## 1๋‹จ๊ณ„: Laravel ๋ฐฑ์—”๋“œ API ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ

Laravel 13.x ์ตœ์‹  ๋ฒ„์ „์œผ๋กœ API ๋ฐฑ์—”๋“œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ธฐ๋ณธ ์„ค์ •์„ ์™„๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

### ์š”๊ตฌ์‚ฌํ•ญ:

1. `backend` ํด๋”์— Laravel 13.x ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ
2. SQLite ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค์ • (.env ํŒŒ์ผ ์ˆ˜์ •)
3. CORS ์„ค์ • (React ํ”„๋ก ํŠธ์—”๋“œ์—์„œ API ํ˜ธ์ถœ ๊ฐ€๋Šฅํ•˜๋„๋ก)
4. ๋‹ค์Œ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํŒŒ์ผ ์ƒ์„ฑ:
   - `quizzes` ํ…Œ์ด๋ธ”: id, title, category, difficulty, question_count, timestamps
   - `questions` ํ…Œ์ด๋ธ”: id, quiz_id (foreign key), question_text, option_a, option_b, option_c, option_d, correct_answer, timestamps
   - `quiz_results` ํ…Œ์ด๋ธ”: id, quiz_id (foreign key), player_name, score, correct_count, total_time, timestamps
5. ๊ฐ ํ…Œ์ด๋ธ”์— ๋Œ€์‘ํ•˜๋Š” Eloquent ๋ชจ๋ธ ์ƒ์„ฑ (Quiz, Question, QuizResult)
6. ๊ด€๊ณ„ ์„ค์ •:
   - Quiz hasMany Questions
   - Quiz hasMany QuizResults
7. API ๋ผ์šฐํŠธ ์„ค๊ณ„ (routes/api.php):
   - GET /api/quizzes (ํ€ด์ฆˆ ๋ชฉ๋ก ์กฐํšŒ)
   - POST /api/quizzes (ํ€ด์ฆˆ ์ƒ์„ฑ)
   - GET /api/quizzes/{id} (ํ€ด์ฆˆ ์ƒ์„ธ ์กฐํšŒ - ๋ฌธ์ œ ํฌํ•จ)
   - POST /api/quiz-results (ํ€ด์ฆˆ ๊ฒฐ๊ณผ ์ œ์ถœ)
   - GET /api/quiz-results/{quizId} (ํŠน์ • ํ€ด์ฆˆ์˜ ๊ฒฐ๊ณผ ๋ชฉ๋ก)
8. ์ปจํŠธ๋กค๋Ÿฌ ์ƒ์„ฑ (QuizController, QuizResultController)
9. Seeder ์ž‘์„ฑ (์ƒ˜ํ”Œ ํ€ด์ฆˆ ๋ฐ์ดํ„ฐ 5๊ฐœ, ๊ฐ ํ€ด์ฆˆ๋‹น 5๊ฐœ ๋ฌธ์ œ)

### ๋ช…๋ น์–ด ์˜ˆ์‹œ:
```bash
composer create-project laravel/laravel:^13.0 backend
cd backend
php artisan migrate
php artisan db:seed
php artisan serve --port=8000
```

### ์นดํ…Œ๊ณ ๋ฆฌ ์˜ˆ์‹œ:
- ์˜ํ™”
- ์Œ์•…
- ์Šคํฌ์ธ 
- ๊ณผํ•™
- ์—ญ์‚ฌ

### ๋‚œ์ด๋„:
- easy (์‰ฌ์›€)
- medium (๋ณดํ†ต)
- hard (์–ด๋ ค์›€)

๋ชจ๋“  ์„ค์ •์ด ์™„๋ฃŒ๋˜๋ฉด `php artisan serve`๋กœ ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•˜๊ณ , Postman์ด๋‚˜ curl๋กœ API๊ฐ€ ์ •์ƒ ์ž‘๋™ํ•˜๋Š”์ง€ ํ…Œ์ŠคํŠธํ•ด์ฃผ์„ธ์š”.

๊ธฐ๋Œ€ ๊ฒฐ๊ณผ: Laravel ๋ฐฑ์—”๋“œ API ์„œ๋ฒ„๊ฐ€ http://localhost:8000 ์—์„œ ์‹คํ–‰๋˜๊ณ , ๋‹ค์Œ์ด ์™„๋ฃŒ๋จ: - SQLite DB ์ƒ์„ฑ ๋ฐ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์™„๋ฃŒ - Quiz, Question, QuizResult ๋ชจ๋ธ ๋ฐ ๊ด€๊ณ„ ์„ค์ • - RESTful API ์—”๋“œํฌ์ธํŠธ ๊ตฌํ˜„ (CRUD) - ์ƒ˜ํ”Œ ๋ฐ์ดํ„ฐ 5๊ฐœ ํ€ด์ฆˆ, ๊ฐ 5๊ฐœ ๋ฌธ์ œ ์‹œ๋”ฉ - CORS ์„ค์ •์œผ๋กœ React์—์„œ API ํ˜ธ์ถœ ๊ฐ€๋Šฅ - Postman์œผ๋กœ GET /api/quizzes ํ˜ธ์ถœ ์‹œ ํ€ด์ฆˆ ๋ชฉ๋ก JSON ์‘๋‹ต ํ™•์ธ

2
Step 2
## 2๋‹จ๊ณ„: React ํ”„๋ก ํŠธ์—”๋“œ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ ๋ฐ ๊ธฐ๋ณธ UI ๊ตฌ์„ฑ

Vite ๊ธฐ๋ฐ˜ React 19 ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , Tailwind CSS๋ฅผ ์„ค์ •ํ•œ ํ›„ ๊ธฐ๋ณธ ๋ ˆ์ด์•„์›ƒ๊ณผ ํ€ด์ฆˆ ๋ชฉ๋ก ํŽ˜์ด์ง€๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

### ์š”๊ตฌ์‚ฌํ•ญ:

1. `frontend` ํด๋”์— Vite + React 19 ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ
2. Tailwind CSS ์„ค์น˜ ๋ฐ ์„ค์ •
3. React Router DOM v6 ์„ค์น˜ (ํŽ˜์ด์ง€ ๋ผ์šฐํŒ…)
4. ๋‹ค์Œ ํŽ˜์ด์ง€ ์ปดํฌ๋„ŒํŠธ ์ƒ์„ฑ:
   - `HomePage.jsx` (ํ€ด์ฆˆ ๋ชฉ๋ก ํŽ˜์ด์ง€)
   - `CreateQuizPage.jsx` (ํ€ด์ฆˆ ์ƒ์„ฑ ํŽ˜์ด์ง€)
   - `QuizPlayPage.jsx` (ํ€ด์ฆˆ ํ”Œ๋ ˆ์ด ํŽ˜์ด์ง€)
   - `ResultPage.jsx` (๊ฒฐ๊ณผ ํŽ˜์ด์ง€)
5. `App.jsx`์—์„œ React Router๋กœ ๋ผ์šฐํŒ… ์„ค์ •
6. `HomePage.jsx` ๊ตฌํ˜„:
   - useState๋กœ ํ€ด์ฆˆ ๋ชฉ๋ก ์ƒํƒœ ๊ด€๋ฆฌ
   - useEffect์—์„œ fetch๋กœ Laravel API (http://localhost:8000/api/quizzes) ํ˜ธ์ถœํ•˜์—ฌ ํ€ด์ฆˆ ๋ชฉ๋ก ๊ฐ€์ ธ์˜ค๊ธฐ
   - ํ€ด์ฆˆ ๋ชฉ๋ก์„ ์นด๋“œ ํ˜•ํƒœ๋กœ ํ‘œ์‹œ (์ œ๋ชฉ, ์นดํ…Œ๊ณ ๋ฆฌ, ๋‚œ์ด๋„, ๋ฌธ์ œ ๊ฐœ์ˆ˜)
   - ๊ฐ ์นด๋“œ ํด๋ฆญ ์‹œ ํ•ด๋‹น ํ€ด์ฆˆ ํ”Œ๋ ˆ์ด ํŽ˜์ด์ง€๋กœ ์ด๋™ (Link ์‚ฌ์šฉ)
   - "์ƒˆ ํ€ด์ฆˆ ๋งŒ๋“ค๊ธฐ" ๋ฒ„ํŠผ (CreateQuizPage๋กœ ์ด๋™)
7. ํ—ค๋” ์ปดํฌ๋„ŒํŠธ ์ƒ์„ฑ (`Header.jsx`):
   - ๋กœ๊ณ /ํƒ€์ดํ‹€ "ํ€ด์ฆˆ ๋ฐฐํ‹€ ์•„๋ ˆ๋‚˜ ๐ŸŽฏ"
   - ํ™ˆ/ํ€ด์ฆˆ ์ƒ์„ฑ ๋„ค๋น„๊ฒŒ์ด์…˜ ๋งํฌ
8. Tailwind CSS๋กœ ๊ฒŒ์ž„๋‹ค์šด ๋””์ž์ธ:
   - ๊ทธ๋ผ๋ฐ์ด์…˜ ๋ฐฐ๊ฒฝ
   - ์นด๋“œ ํ˜ธ๋ฒ„ ํšจ๊ณผ (scale, shadow)
   - ๋ฒ„ํŠผ ์• ๋‹ˆ๋ฉ”์ด์…˜
   - ๋ฐ˜์‘ํ˜• ๊ทธ๋ฆฌ๋“œ ๋ ˆ์ด์•„์›ƒ (๋ชจ๋ฐ”์ผ: 1์—ด, ํƒœ๋ธ”๋ฆฟ: 2์—ด, ๋ฐ์Šคํฌํ†ฑ: 3์—ด)

### ๋ช…๋ น์–ด ์˜ˆ์‹œ:
```bash
cd ..
npm create vite@latest frontend -- --template react
cd frontend
npm install
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
npm install react-router-dom
npm run dev
```

### ๋””์ž์ธ ์ปจ์…‰:
- ๋ฐฐ๊ฒฝ: ๋ณด๋ผ-ํŒŒ๋ž‘ ๊ทธ๋ผ๋ฐ์ด์…˜
- ์นด๋“œ: ํฐ์ƒ‰ ๋ฐฐ๊ฒฝ, ๋‘ฅ๊ทผ ๋ชจ์„œ๋ฆฌ, ๊ทธ๋ฆผ์ž
- ๋ฒ„ํŠผ: ์ฃผํ™ฉ์ƒ‰ ๋˜๋Š” ํŒŒ๋ž€์ƒ‰, ํ˜ธ๋ฒ„ ์‹œ ์‚ด์ง ์ปค์ง
- ํฐํŠธ: ๊ตต์€ ์ œ๋ชฉ, ๊น”๋”ํ•œ ๋ณธ๋ฌธ

ํ”„๋ก ํŠธ์—”๋“œ ์„œ๋ฒ„๊ฐ€ http://localhost:5173 ์—์„œ ์‹คํ–‰๋˜๊ณ , ํ™ˆํŽ˜์ด์ง€์—์„œ Laravel API๋กœ๋ถ€ํ„ฐ ํ€ด์ฆˆ ๋ชฉ๋ก์„ ๋ถˆ๋Ÿฌ์™€ ์นด๋“œ๋กœ ํ‘œ์‹œ๋˜๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”.

๊ธฐ๋Œ€ ๊ฒฐ๊ณผ: React ํ”„๋ก ํŠธ์—”๋“œ๊ฐ€ http://localhost:5173 ์—์„œ ์‹คํ–‰๋˜๊ณ , ๋‹ค์Œ์ด ์™„๋ฃŒ๋จ: - Vite + React 19 ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ - Tailwind CSS ์„ค์ • ์™„๋ฃŒ - React Router๋กœ ํŽ˜์ด์ง€ ๋ผ์šฐํŒ… ๊ตฌ์„ฑ - HomePage์—์„œ fetch๋กœ Laravel API ํ˜ธ์ถœํ•˜์—ฌ ํ€ด์ฆˆ ๋ชฉ๋ก ํ‘œ์‹œ - ํ€ด์ฆˆ ์นด๋“œ๊ฐ€ ๊ทธ๋ฆฌ๋“œ ํ˜•ํƒœ๋กœ ํ‘œ์‹œ๋˜๋ฉฐ, ํ˜ธ๋ฒ„ ์‹œ ์• ๋‹ˆ๋ฉ”์ด์…˜ ํšจ๊ณผ - ํ—ค๋”์— ๋„ค๋น„๊ฒŒ์ด์…˜ ๋งํฌ ํ‘œ์‹œ - ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ์ ์šฉ (๋ชจ๋ฐ”์ผ/ํƒœ๋ธ”๋ฆฟ/๋ฐ์Šคํฌํ†ฑ)

3
Step 3
## 3๋‹จ๊ณ„: ํ€ด์ฆˆ ํ”Œ๋ ˆ์ด ํŽ˜์ด์ง€ ๋ฐ ๊ฒฐ๊ณผ ์ œ์ถœ ๊ธฐ๋Šฅ ๊ตฌํ˜„

์‚ฌ์šฉ์ž๊ฐ€ ํ€ด์ฆˆ๋ฅผ ํ”Œ๋ ˆ์ดํ•˜๊ณ , ์ •๋‹ต์„ ์„ ํƒํ•˜๋ฉฐ, ๊ฒฐ๊ณผ๋ฅผ ์ œ์ถœํ•˜๋Š” ์ „์ฒด ํ”Œ๋กœ์šฐ๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

### ์š”๊ตฌ์‚ฌํ•ญ:

1. `QuizPlayPage.jsx` ๊ตฌํ˜„:
   - URL ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ quizId ๋ฐ›๊ธฐ (useParams)
   - useEffect์—์„œ GET /api/quizzes/{quizId} ํ˜ธ์ถœํ•˜์—ฌ ํ€ด์ฆˆ ๋ฐ์ดํ„ฐ(๋ฌธ์ œ ํฌํ•จ) ๊ฐ€์ ธ์˜ค๊ธฐ
   - useState๋กœ ๋‹ค์Œ ์ƒํƒœ ๊ด€๋ฆฌ:
     - currentQuestionIndex (ํ˜„์žฌ ๋ฌธ์ œ ์ธ๋ฑ์Šค, ์ดˆ๊ธฐ๊ฐ’ 0)
     - selectedAnswer (์„ ํƒํ•œ ๋‹ต)
     - score (์ ์ˆ˜)
     - correctCount (๋งžํžŒ ๊ฐœ์ˆ˜)
     - isAnswered (ํ˜„์žฌ ๋ฌธ์ œ์— ๋‹ตํ–ˆ๋Š”์ง€ ์—ฌ๋ถ€)
     - startTime (ํ€ด์ฆˆ ์‹œ์ž‘ ์‹œ๊ฐ„)
   - ํ˜„์žฌ ๋ฌธ์ œ ํ‘œ์‹œ:
     - ๋ฌธ์ œ ํ…์ŠคํŠธ
     - 4๊ฐœ์˜ ์„ ํƒ์ง€ ๋ฒ„ํŠผ (option_a, option_b, option_c, option_d)
     - ์„ ํƒ์ง€ ํด๋ฆญ ์‹œ selectedAnswer ์—…๋ฐ์ดํŠธ ๋ฐ isAnswered๋ฅผ true๋กœ ์„ค์ •
   - ์ •๋‹ต ํ™•์ธ ๋กœ์ง:
     - ์„ ํƒํ•œ ๋‹ต๊ณผ correct_answer ๋น„๊ต
     - ์ •๋‹ต์ด๋ฉด score +10, correctCount +1
     - ์ •๋‹ต/์˜ค๋‹ต ํ”ผ๋“œ๋ฐฑ ํ‘œ์‹œ (์ดˆ๋ก์ƒ‰/๋นจ๊ฐ„์ƒ‰ ๋ฐฐ๊ฒฝ, ๋ฉ”์‹œ์ง€)
   - "๋‹ค์Œ ๋ฌธ์ œ" ๋ฒ„ํŠผ:
     - ํด๋ฆญ ์‹œ currentQuestionIndex +1
     - ๋งˆ์ง€๋ง‰ ๋ฌธ์ œ๋ผ๋ฉด ๊ฒฐ๊ณผ ์ œ์ถœ ๋ฐ ResultPage๋กœ ์ด๋™
   - ํƒ€์ด๋จธ (์„ ํƒ ๊ธฐ๋Šฅ, ๋ณด๋„ˆ์Šค):
     - 30์ดˆ ์นด์šดํŠธ๋‹ค์šด
     - ์‹œ๊ฐ„ ์ดˆ๊ณผ ์‹œ ์ž๋™์œผ๋กœ ๋‹ค์Œ ๋ฌธ์ œ๋กœ ๋„˜์–ด๊ฐ
     - ์ง„ํ–‰๋ฐ”๋กœ ์‹œ๊ฐํ™” (์‹œ๊ฐ„์ด ์ค„์–ด๋“ค์ˆ˜๋ก ๋นจ๊ฐ„์ƒ‰์œผ๋กœ ๋ณ€ํ™”)
2. ๊ฒฐ๊ณผ ์ œ์ถœ:
   - ๋ชจ๋“  ๋ฌธ์ œ๋ฅผ ํ’€๋ฉด POST /api/quiz-results๋กœ ๊ฒฐ๊ณผ ์ œ์ถœ
   - ์š”์ฒญ ๋ณธ๋ฌธ: { quiz_id, player_name, score, correct_count, total_time }
   - player_name์€ ๊ฐ„๋‹จํ•œ ์ž…๋ ฅ ํผ์œผ๋กœ ๋ฐ›๊ฑฐ๋‚˜ "์ต๋ช…" ๊ธฐ๋ณธ๊ฐ’ ์‚ฌ์šฉ
   - ์ œ์ถœ ํ›„ ResultPage๋กœ ์ด๋™ (navigate ์‚ฌ์šฉ)
3. `ResultPage.jsx` ๊ตฌํ˜„:
   - URL state๋กœ ์ „๋‹ฌ๋ฐ›์€ ๊ฒฐ๊ณผ ๋ฐ์ดํ„ฐ ํ‘œ์‹œ
   - ์ตœ์ข… ์ ์ˆ˜, ๋งžํžŒ ๊ฐœ์ˆ˜ / ์ „์ฒด ๋ฌธ์ œ ์ˆ˜, ์ •๋‹ต๋ฅ  (%)
   - "๋‹ค์‹œ ๋„์ „ํ•˜๊ธฐ" ๋ฒ„ํŠผ (๊ฐ™์€ ํ€ด์ฆˆ ๋‹ค์‹œ ํ”Œ๋ ˆ์ด)
   - "ํ™ˆ์œผ๋กœ ๋Œ์•„๊ฐ€๊ธฐ" ๋ฒ„ํŠผ
   - (๋ณด๋„ˆ์Šค) GET /api/quiz-results/{quizId} ํ˜ธ์ถœํ•˜์—ฌ ๋‹ค๋ฅธ ํ”Œ๋ ˆ์ด์–ด๋“ค์˜ ์ ์ˆ˜ ๋ฆฌ๋”๋ณด๋“œ ํ‘œ์‹œ
4. ์• ๋‹ˆ๋ฉ”์ด์…˜ ํšจ๊ณผ:
   - ๋ฌธ์ œ ์ „ํ™˜ ์‹œ ์นด๋“œ ํ”Œ๋ฆฝ ๋˜๋Š” ํŽ˜์ด๋“œ ์ธ/์•„์›ƒ
   - ์ •๋‹ต ์‹œ ์ถ•ํ•˜ ํšจ๊ณผ (confetti ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ ๊ฐ€๋Šฅ, ์„ ํƒ)
   - ๋ฒ„ํŠผ ํ˜ธ๋ฒ„ ์‹œ scale ์• ๋‹ˆ๋ฉ”์ด์…˜

### ํ”Œ๋ ˆ์ด์–ด ์ด๋ฆ„ ์ž…๋ ฅ:
- ํ€ด์ฆˆ ์‹œ์ž‘ ์ „ ๊ฐ„๋‹จํ•œ ๋ชจ๋‹ฌ ๋˜๋Š” ์ž…๋ ฅ ํ•„๋“œ๋กœ ์ด๋ฆ„ ์ž…๋ ฅ๋ฐ›๊ธฐ
- localStorage์— ์ €์žฅํ•˜์—ฌ ๋‹ค์Œ์—๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

### ๋””์ž์ธ:
- ๋ฌธ์ œ ์นด๋“œ: ํฐ ํฐํŠธ, ์ค‘์•™ ์ •๋ ฌ
- ์„ ํƒ์ง€ ๋ฒ„ํŠผ: 4๊ฐœ๊ฐ€ 2x2 ๊ทธ๋ฆฌ๋“œ ๋˜๋Š” ์„ธ๋กœ๋กœ ๋‚˜์—ด
- ์ •๋‹ต ํ”ผ๋“œ๋ฐฑ: ํ™”๋ฉด ์ƒ๋‹จ์— ํ† ์ŠคํŠธ ๋ฉ”์‹œ์ง€ ๋˜๋Š” ๋ชจ๋‹ฌ
- ๊ฒฐ๊ณผ ํŽ˜์ด์ง€: ํฐ ์ ์ˆ˜ ์ˆซ์ž, ์ถ•ํ•˜ ๋ฉ”์‹œ์ง€, ์ด๋ชจ์ง€

๋ชจ๋“  ๊ธฐ๋Šฅ์ด ์™„๋ฃŒ๋˜๋ฉด ํ€ด์ฆˆ๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ ํ”Œ๋ ˆ์ดํ•˜๊ณ , ๊ฒฐ๊ณผ๊ฐ€ DB์— ์ €์žฅ๋˜๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”.

๊ธฐ๋Œ€ ๊ฒฐ๊ณผ: QuizPlayPage์—์„œ ํ€ด์ฆˆ๋ฅผ ํ”Œ๋ ˆ์ดํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋‹ค์Œ์ด ์™„๋ฃŒ๋จ: - API๋กœ๋ถ€ํ„ฐ ํ€ด์ฆˆ ๋ฌธ์ œ ๋ฐ์ดํ„ฐ ๋กœ๋“œ - ์„ ํƒ์ง€ ํด๋ฆญ์œผ๋กœ ๋‹ต ์„ ํƒ ๋ฐ ์ •๋‹ต ํ™•์ธ - ๋งžํžŒ ๊ฐœ์ˆ˜์™€ ์ ์ˆ˜ ๊ณ„์‚ฐ - ๋ชจ๋“  ๋ฌธ์ œ ์™„๋ฃŒ ํ›„ POST /api/quiz-results๋กœ ๊ฒฐ๊ณผ ์ œ์ถœ - ResultPage์—์„œ ์ตœ์ข… ์ ์ˆ˜, ์ •๋‹ต๋ฅ , ๋ฆฌ๋”๋ณด๋“œ ํ‘œ์‹œ - ์• ๋‹ˆ๋ฉ”์ด์…˜ ํšจ๊ณผ (๋ฌธ์ œ ์ „ํ™˜, ์ •๋‹ต ํ”ผ๋“œ๋ฐฑ) - ํƒ€์ด๋จธ ๊ธฐ๋Šฅ (์„ ํƒ) - ๋ฐ˜์‘ํ˜• ๋””์ž์ธ์œผ๋กœ ๋ชจ๋ฐ”์ผ์—์„œ๋„ ์พŒ์ ํ•˜๊ฒŒ ํ”Œ๋ ˆ์ด ๊ฐ€๋Šฅ

์ œ์ถœ๋œ ์ž‘ํ’ˆ (0)

๋กœ๊ทธ์ธ ํ›„ ์ œ์ถœ

์•„์ง ์ œ์ถœ๋œ ์ž‘ํ’ˆ์ด ์—†์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋„์ „์ž๊ฐ€ ๋˜์–ด๋ณด์„ธ์š”!

๋Œ“๊ธ€ (0)

๋กœ๊ทธ์ธ ํ›„ ๋Œ“๊ธ€์„ ๋‚จ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์•„์ง ๋Œ“๊ธ€์ด ์—†์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋Œ“๊ธ€์„ ๋‚จ๊ฒจ๋ณด์„ธ์š”!