# 03. 학습 내용 선택과 숫자 괄호 준비 화면 ## 계획 평가 Codex가 작성한 기존 계획은 방향이 맞다. `StartControls.tsx` 이동, `/number-parentheses` 라우트 신설, 첫 화면을 학습 내용 선택으로 전환하는 흐름이 현재 코드 구조와 잘 맞는다. 다만 실제 코드 상태와 맞추어 조정할 부분이 있다. - `PlayClient`는 URL `?count=N`으로 문제 수를 받고, `gameStore`에 `selectedProblemCount`와 `setProblemCount`가 이미 구현되어 있다. 준비 화면에서 이 흐름을 그대로 이어받으면 된다. - 괄호 종류 선택은 이번 단계에서 UI만 추가한다. `()`만 선택 가능하고 `{}`, `[]`는 disabled로 표시한다. 괄호 종류를 Zustand나 URL에 저장하는 것은 실제 문제 생성이 지원할 때로 미룬다. - `app/StartControls.tsx`는 준비 화면으로 내용을 옮긴 뒤 삭제한다. - 문제 풀이 화면(`PlayClient.tsx`, `play/page.tsx`)은 이번 단계에서 수정하지 않는다. --- ## 목표 앞으로 학습 내용을 계속 추가할 수 있도록 첫 화면을 학습 내용 선택 화면으로 바꾸고, 현재 숫자 괄호 풀이 시작 기능을 별도 준비 화면으로 분리한다. 이번 단계의 최종 상태는 다음과 같다. - `/`에서 학습 내용을 선택한다. - `숫자 괄호`를 선택하면 문제 수와 괄호 종류를 고르는 준비 화면으로 이동한다. - 분수 괄호, 실수 괄호, 미지수 괄호는 버튼만 표시하고 비활성화한다. - `/play` 문제 풀이 화면과 풀이 로직은 현재 동작 그대로 유지한다. --- ## 이번 단계에서 할 것 - `app/page.tsx`를 학습 내용 선택 화면으로 교체 - `app/(game)/number-parentheses/page.tsx`, `NumberParenthesesClient.tsx` 신규 생성 - `StartControls.tsx`의 문제 수 선택과 연습 시작 흐름을 준비 화면으로 이동 - 준비 화면에 괄호 종류 버튼 그룹 추가 (`()` 선택 가능, `{}` / `[]` disabled) - `app/StartControls.tsx` 삭제 ## 이번 단계에서 하지 않을 것 - 분수 괄호, 실수 괄호, 미지수 괄호 문제 생성 - `{}`, `[]` 괄호 문제 생성 - 괄호 종류를 Zustand나 URL에 저장 - 문제 풀이 화면 UI 수정 - 새로운 게임 모드 추가 - DB, Redis, NextAuth --- ## 생성 또는 수정 파일 ### 신규 생성 ```text app/(game)/number-parentheses/page.tsx app/(game)/number-parentheses/NumberParenthesesClient.tsx ``` ### 수정 ```text app/page.tsx ``` ### 삭제 ```text app/StartControls.tsx ``` ### 변경 없음 ```text app/(game)/play/page.tsx app/(game)/play/PlayClient.tsx store/gameStore.ts lib/engine/ components/ ``` --- ## 작업 순서 ### 3-A. 숫자 괄호 준비 화면 신설 완료 기준: `/number-parentheses`에서 문제 수를 고르고 연습을 시작할 수 있다. `app/(game)/number-parentheses/page.tsx`는 Server Component 래퍼로 만든다. ```tsx import NumberParenthesesClient from './NumberParenthesesClient' export default function NumberParenthesesPage() { return } ``` `app/(game)/number-parentheses/NumberParenthesesClient.tsx`에는 `'use client'`를 붙이고, 현재 `StartControls.tsx`의 내용을 기반으로 구성한다. **문제 수 버튼 그룹** 현재 `StartControls.tsx`의 문제 수 선택 로직을 그대로 가져온다. - `useGameStore`에서 `selectedProblemCount`, `setProblemCount`, `initSession`을 가져온다. - `5`, `10` 버튼 그룹 (기본값 `10`) - 선택된 문제 수는 `selectedProblemCount`로 표시한다. **괄호 종류 버튼 그룹** ```tsx type BracketKind = 'round' | 'curly' | 'square' const brackets: { kind: BracketKind; label: string; disabled: boolean }[] = [ { kind: 'round', label: '( )', disabled: false }, { kind: 'curly', label: '{ }', disabled: true }, { kind: 'square', label: '[ ]', disabled: true }, ] ``` - `round`는 항상 selected 상태로 고정 표시한다. - `curly`, `square`는 disabled 스타일을 적용하고 클릭을 막는다. - 괄호 종류 상태를 useState나 Zustand에 저장하지 않는다. 이번 단계에서는 `()` 하나만 유효하다. **연습 시작 버튼** 현재 `StartControls.tsx`의 Link를 그대로 가져온다. ```tsx initSession(selectedProblemCount)} > 연습 시작 ``` **뒤로 가기 링크** 준비 화면에서 첫 화면으로 돌아갈 수 있도록 "처음으로" 링크를 추가한다. ```tsx 처음으로 ``` --- ### 3-B. 첫 화면을 학습 내용 선택으로 교체 완료 기준: `/`에서 네 가지 학습 내용 버튼이 표시된다. `app/page.tsx`를 수정한다. - 제목과 안내 문구를 여러 학습 내용을 선택하는 맥락으로 바꾼다. - `StartControls` 호출을 제거한다. - 학습 내용 목록을 렌더링한다. 버튼 목록: | 학습 내용 | 상태 | 이동 | |---|---|---| | 숫자 괄호 | 활성 | `/number-parentheses` | | 분수 괄호 | disabled | — | | 실수 괄호 | disabled | — | | 미지수 괄호 | disabled | — | 활성 버튼은 `Link`로, disabled 버튼은 `