Files
math-quiz/docs/vibe/03-select-subject.md

7.6 KiB

03. 학습 내용 선택과 숫자 괄호 준비 화면

계획 평가

Codex가 작성한 기존 계획은 방향이 맞다. StartControls.tsx 이동, /number-parentheses 라우트 신설, 첫 화면을 학습 내용 선택으로 전환하는 흐름이 현재 코드 구조와 잘 맞는다.

다만 실제 코드 상태와 맞추어 조정할 부분이 있다.

  • PlayClient는 URL ?count=N으로 문제 수를 받고, gameStoreselectedProblemCountsetProblemCount가 이미 구현되어 있다. 준비 화면에서 이 흐름을 그대로 이어받으면 된다.
  • 괄호 종류 선택은 이번 단계에서 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

생성 또는 수정 파일

신규 생성

app/(game)/number-parentheses/page.tsx
app/(game)/number-parentheses/NumberParenthesesClient.tsx

수정

app/page.tsx

삭제

app/StartControls.tsx

변경 없음

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 래퍼로 만든다.

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로 표시한다.

괄호 종류 버튼 그룹

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를 그대로 가져온다.

<Link
  href={`/play?count=${selectedProblemCount}`}
  onClick={() => initSession(selectedProblemCount)}
>
  연습 시작
</Link>

뒤로 가기 링크

준비 화면에서 첫 화면으로 돌아갈 수 있도록 "처음으로" 링크를 추가한다.

<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를 참조하는 파일이 없는지 확인한다.

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 이동 확인

화면 흐름

/ 학습 내용 선택
  - [숫자 괄호 풀기]      → /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 통과

확인 명령

pnpm build
pnpm test
pnpm dev

다음 단계

새 학습 내용(분수 괄호, 실수 괄호, 미지수 괄호)을 추가할 때는 다음 순서로 확장한다.

  1. lib/engine/에 해당 유형의 문제 생성 함수 추가
  2. app/(game)/number-parentheses/NumberParenthesesClient.tsx의 괄호 종류 버튼에서 disabled 해제
  3. 괄호 종류를 Zustand나 URL 파라미터로 저장하고 initSession에 파라미터 연결