247 lines
7.6 KiB
Markdown
247 lines
7.6 KiB
Markdown
# 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 <NumberParenthesesClient />
|
|
}
|
|
```
|
|
|
|
`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
|
|
<Link
|
|
href={`/play?count=${selectedProblemCount}`}
|
|
onClick={() => initSession(selectedProblemCount)}
|
|
>
|
|
연습 시작
|
|
</Link>
|
|
```
|
|
|
|
**뒤로 가기 링크**
|
|
|
|
준비 화면에서 첫 화면으로 돌아갈 수 있도록 "처음으로" 링크를 추가한다.
|
|
|
|
```tsx
|
|
<Link href="/">처음으로</Link>
|
|
```
|
|
|
|
---
|
|
|
|
### 3-B. 첫 화면을 학습 내용 선택으로 교체
|
|
|
|
완료 기준: `/`에서 네 가지 학습 내용 버튼이 표시된다.
|
|
|
|
`app/page.tsx`를 수정한다.
|
|
|
|
- 제목과 안내 문구를 여러 학습 내용을 선택하는 맥락으로 바꾼다.
|
|
- `StartControls` 호출을 제거한다.
|
|
- 학습 내용 목록을 렌더링한다.
|
|
|
|
버튼 목록:
|
|
|
|
| 학습 내용 | 상태 | 이동 |
|
|
|---|---|---|
|
|
| 숫자 괄호 | 활성 | `/number-parentheses` |
|
|
| 분수 괄호 | disabled | — |
|
|
| 실수 괄호 | disabled | — |
|
|
| 미지수 괄호 | disabled | — |
|
|
|
|
활성 버튼은 `Link`로, disabled 버튼은 `<button disabled>`으로 만든다.
|
|
클라이언트 기능이 없으므로 `page.tsx` 자체에 인라인으로 구성하고 별도 컴포넌트로 분리하지 않는다.
|
|
|
|
---
|
|
|
|
### 3-C. StartControls.tsx 삭제 및 회귀 확인
|
|
|
|
완료 기준: `숫자 괄호`부터 결과 화면까지 기존 풀이가 동작한다.
|
|
|
|
`app/StartControls.tsx`를 삭제한다.
|
|
|
|
삭제 전에 `StartControls`를 참조하는 파일이 없는지 확인한다.
|
|
|
|
```bash
|
|
grep -r "StartControls" /Users/jisangs/work/jinaju/git/web/math-quiz/app
|
|
```
|
|
|
|
풀이 흐름을 처음부터 끝까지 수동으로 확인한다.
|
|
|
|
1. `/` 접속 → 학습 내용 선택 화면 표시 확인
|
|
2. `숫자 괄호` 클릭 → `/number-parentheses` 이동 확인
|
|
3. 문제 수 `5` 선택 → `연습 시작` 클릭 → `/play?count=5` 이동 확인
|
|
4. 5문제 세션 완료 → 점수 요약 표시 확인
|
|
5. `다시 시작` 클릭 → 새 세션 확인
|
|
6. `/number-parentheses`로 돌아와 문제 수 `10` 선택 → `/play?count=10` 이동 확인
|
|
|
|
---
|
|
|
|
## 화면 흐름
|
|
|
|
```text
|
|
/ 학습 내용 선택
|
|
- [숫자 괄호 풀기] → /number-parentheses
|
|
- [분수 괄호 풀기] disabled
|
|
- [실수 괄호 풀기] disabled
|
|
- [미지수 괄호 풀기] disabled
|
|
|
|
↓
|
|
|
|
/number-parentheses 숫자 괄호 준비
|
|
- 문제 수: [5] [10]
|
|
- 괄호 종류: [( )] [{} disabled] [[] disabled]
|
|
- [연습 시작] → /play?count=N
|
|
- [처음으로] → /
|
|
|
|
↓
|
|
|
|
/play 문제 풀이 (현재 동작 유지)
|
|
```
|
|
|
|
---
|
|
|
|
## 완료 기준
|
|
|
|
- `/`가 학습 내용 선택 화면으로 표시된다.
|
|
- `숫자 괄호` 버튼으로 `/number-parentheses`에 진입할 수 있다.
|
|
- `분수 괄호`, `실수 괄호`, `미지수 괄호`는 disabled 상태다.
|
|
- 준비 화면에서 문제 수 `5`, `10`을 선택할 수 있다.
|
|
- 준비 화면에서 `()` 괄호 종류가 선택 상태로 표시된다.
|
|
- `{}`, `[]` 괄호 종류는 disabled 상태다.
|
|
- `연습 시작`으로 기존 `/play` 문제 풀이 화면에 진입한다.
|
|
- `/play`의 문제 풀이 동작은 기존과 동일하다.
|
|
- `pnpm build` 통과
|
|
- `pnpm test` 통과
|
|
|
|
## 확인 명령
|
|
|
|
```bash
|
|
pnpm build
|
|
pnpm test
|
|
pnpm dev
|
|
```
|
|
|
|
---
|
|
|
|
## 다음 단계
|
|
|
|
새 학습 내용(분수 괄호, 실수 괄호, 미지수 괄호)을 추가할 때는 다음 순서로 확장한다.
|
|
|
|
1. `lib/engine/`에 해당 유형의 문제 생성 함수 추가
|
|
2. `app/(game)/number-parentheses/NumberParenthesesClient.tsx`의 괄호 종류 버튼에서 disabled 해제
|
|
3. 괄호 종류를 Zustand나 URL 파라미터로 저장하고 `initSession`에 파라미터 연결
|