Skip to content

Conversation

@cl-o-lc
Copy link
Collaborator

@cl-o-lc cl-o-lc commented Sep 19, 2025

📌 작업 내용

  • 반응속도 측정 미니게임 구현
  • 전역 헤더 ui 적용

📸 스크린샷

image

📝 기타

  • 추후 db에 기록 저장하고, 활용할 계획 (현재는 로컬 저장)

Summary by CodeRabbit

  • New Features
    • 반응속도 게임 페이지 추가: 시작/결과/평균/최고 기록 표시, 기록 초기화 및 팁 제공.
    • 전역 헤더 도입: 로그인/회원가입/로그아웃 모달, 탭 간 동기화 및 자동 상태 유지.
    • 헤더 내 “반응속도 게임” 링크가 실제 경로(/reaction-test)로 연결.
  • Refactor
    • 홈 화면 간소화: 히어로/URL 입력/현재 시간만 표시하도록 인증 관련 UI 제거.
    • 회원가입 모달의 제출 페이로드 필드명이 username → userName으로 변경 (연동 주의).

@cl-o-lc cl-o-lc self-assigned this Sep 19, 2025
@coderabbitai
Copy link

coderabbitai bot commented Sep 19, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

전역 레이아웃에 클라이언트 헤더를 추가했고 홈 페이지에서 인증 관련 상태/모달/로컬스토리지 토큰 처리를 제거했습니다. 신규 클라이언트 페이지로 반응속도 게임을 도입했고, 회원가입 모달의 onSubmit 페이로드 필드명을 usernameuserName으로 변경했으며 헤더 링크를 /reaction-test로 갱신했습니다.

Changes

Cohort / File(s) Summary
레이아웃 통합 헤더 도입
src/app/layout.tsx
전역 레이아웃에 ClientHeader 임포트 및 <body> 초입에 <ClientHeader /> 렌더링 추가.
홈 페이지 단순화
src/app/page.tsx
인증 상태, 로그인/회원가입/확인 모달, 로컬스토리지 토큰 처리 및 관련 헤더 사용 제거. 히어로, URL 입력(SearchForm), 현재 시간만 렌더. 검색 제출 시 /result?url=... 네비게이션 유지.
반응속도 게임 신규 페이지
src/app/reaction-test/page.tsx
클라이언트 페이지 추가(Phase: idle→ready→go/tooSoon→result). 랜덤 지연(500–5000ms), 반응시간 측정(performance.now), 기록/평균/최고(localStorage) 관리, 리셋 및 UI 구성.
전역 클라이언트 헤더(인증 제어)
src/components/ClientHeader.tsx
클라이언트 헤더 컴포넌트 추가: 로그인/회원가입/로그아웃 모달 제어, 로컬스토리지 토큰 및 사용자명 동기화(멀티탭), API 연동(/api/auth/login, /api/auth/register), 인증 상태에 따른 헤더 렌더링 및 라우팅 처리.
회원가입 모달 API 변경
src/components/auth/SignupModal.tsx
onSubmit 페이로드 필드 타입/사용을 usernameuserName으로 변경(내부 state/검증/바인딩 동기화).
헤더 내 내비게이션 갱신
src/components/ui/Header.tsx
“반응속도 게임” 링크 href #/reaction-test로 변경(링크 대상 수정).
사소한 UI 포맷/공백 정리
src/app/result/page.tsx, src/components/auth/LoginModal.tsx
JSX 내 불필요한 강제 공백 제거(로직 변경 없음).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User as 사용자
  participant Layout as RootLayout
  participant CH as ClientHeader
  participant LS as localStorage
  participant API as Auth API
  participant Router as Next Router

  Note over Layout,CH: 페이지 렌더링
  User->>Layout: 페이지 요청
  Layout->>CH: 헤더 렌더
  CH->>LS: 토큰/사용자명 로드
  LS-->>CH: 값 반환
  CH-->>User: 로그인/비로그인 UI 표시

  alt 로그인
    User->>CH: 로그인 모달 제출
    CH->>API: POST /api/auth/login
    API-->>CH: 토큰/사용자명
    CH->>LS: 토큰/사용자명 저장
    CH-->>User: 로그인 UI 업데이트
  end

  alt 회원가입
    User->>CH: 회원가입 모달 제출(userName)
    CH->>API: POST /api/auth/register
    API-->>CH: 성공
    CH-->>User: 성공 안내 → 로그인 모달 오픈
  end

  alt 로그아웃
    User->>CH: 로그아웃 확인
    CH->>LS: 토큰/사용자명 제거
    CH->>Router: / 로 이동
    CH-->>User: 비로그인 UI 표시
  end
Loading
sequenceDiagram
  autonumber
  actor User as 사용자
  participant RT as ReactionTest Page
  participant Timer as setTimeout
  participant Perf as performance.now
  participant LS as localStorage

  User->>RT: 게임 시작 클릭
  RT->>Timer: 랜덤 지연 타이머(500–5000ms) 설정
  Timer-->>RT: 타이머 만료(ready→go)
  RT->>Perf: 시작 시각 기록

  alt go 단계에서 클릭
    User->>RT: 원 클릭
    RT->>Perf: 종료 시각 취득
    RT-->>User: 반응시간 표시 및 기록 저장
    RT->>LS: 최고기록 갱신 저장
  else ready 단계에서 실수 클릭
    User->>RT: 원 클릭
    RT-->>User: tooSoon 상태
  end

  User->>RT: 기록 초기화
  RT->>LS: 최고기록 제거
  RT-->>User: 초기 상태 복귀
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

feat🛠️

Poem

깡총깡총, 새 헤더 달고 출발! 🥕
클릭 준비, 초록불에 심장이 쿵쿵 ⏱️
토큰은 주머니에, 기록은 로컬에 쌓아
/reaction-test로 달려가며 웃음 한 모금
토끼가 응원해 — 또 한 번 점프! 🐇

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed 제목은 “[feature] 사용자 반응속도 테스트 기능 구현”으로 변경된 주요 기능인 반응속도 테스트를 명확하고 간결하게 요약하고 있으며 불필요한 정보나 모호한 표현 없이 핵심만 담고 있습니다.
Description Check ✅ Passed 제공된 설명은 “📌 작업 내용”, “📸 스크린샷”, “📝 기타” 세 섹션을 모두 포함해 저장소 템플릿의 구조와 요구 정보를 충족하며 각 섹션이 구체적이고 명확하게 작성되어 있습니다.

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b8e7839 and dd1893b.

📒 Files selected for processing (3)
  • src/app/result/page.tsx (1 hunks)
  • src/components/auth/LoginModal.tsx (1 hunks)
  • src/components/auth/SignupModal.tsx (6 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (8)
src/app/page.tsx (1)

16-16: 불필요한 JSX 주석 제거 필요

Line 16의 {' '} 는 불필요한 빈 공백 렌더링입니다. 제거해도 레이아웃에 영향이 없습니다.

-      {' '}
src/app/reaction-test/page.tsx (4)

16-17: 타입 안정성 향상을 위한 useRef 타입 지정

timerRefstartTsRef의 타입을 더 명확하게 지정하면 타입 안정성이 향상됩니다.

-  const timerRef = useRef<NodeJS.Timeout | null>(null);
-  const startTsRef = useRef<number | null>(null);
+  const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
+  const startTsRef = useRef<DOMHighResTimeStamp | null>(null);

48-49: 랜덤 지연 시간 계산 로직 개선 가능

현재 코드도 정확하지만, 더 간결하게 작성할 수 있습니다.

-    const delay = Math.floor(Math.random() * (max - min + 1)) + min;
+    const delay = Math.floor(Math.random() * (max - min)) + min;

120-129: className 배열 조합 방식 개선

clsx 라이브러리를 사용하면 조건부 클래스를 더 깔끔하게 관리할 수 있습니다.

파일 상단에 import 추가:

import clsx from 'clsx';

그리고 className 로직을 다음과 같이 개선:

-                  className={[
-                    'flex h-64 w-64 items-center justify-center rounded-full border text-gray-700',
-                    circleColor,
-                    phase === 'go'
-                      ? 'border-green-300'
-                      : phase === 'tooSoon'
-                      ? 'border-red-300'
-                      : 'border-gray-200',
-                    'select-none',
-                  ].join(' ')}
+                  className={clsx(
+                    'flex h-64 w-64 items-center justify-center rounded-full border text-gray-700 select-none',
+                    circleColor,
+                    {
+                      'border-green-300': phase === 'go',
+                      'border-red-300': phase === 'tooSoon',
+                      'border-gray-200': phase !== 'go' && phase !== 'tooSoon',
+                    }
+                  )}

165-176: 반응속도 향상 팁 구현 고려사항

팁 섹션이 유용하지만, 실제 티켓팅 환경과 관련된 더 구체적인 조언을 추가하면 좋을 것 같습니다.

예를 들어:

  • 네트워크 지연을 고려한 실제 클릭 타이밍 조언
  • 여러 탭을 미리 열어두는 전략
  • 브라우저 캐시 정리 등의 준비사항
src/components/auth/SignupModal.tsx (1)

22-22: state setter 함수명 불일치

userName state 변수명과 setUsername setter 함수명이 일치하지 않습니다. 일관성을 위해 수정이 필요합니다.

-  const [userName, setUsername] = useState('');
+  const [userName, setUserName] = useState('');

그리고 Line 129에서도 수정:

-              onChange={(e) => setUsername(e.target.value)}
+              onChange={(e) => setUserName(e.target.value)}
src/components/ClientHeader.tsx (2)

124-131: 타입 안전성 개선 권장

Line 126에서 userName ?? ''로 fallback을 처리하고 있지만, Header 컴포넌트의 userName prop이 선택적 타입인지 확인이 필요합니다.

Header 컴포넌트의 타입 정의를 확인하여 일관성을 유지하세요:

#!/bin/bash
# Header 컴포넌트의 props 타입 정의 확인
rg -n "interface.*HeaderProps\|type.*HeaderProps" --type=tsx --type=ts -A10

22-41: 탭 간 인증 상태 동기화 구현이 적절합니다

현재 코드는 localStorage의 storage 이벤트를 활용해 탭 간 로그인/로그아웃 상태를 동기화하며, 기능적으로 올바르게 작동합니다. React 18 공식 문서에서는 외부 스토어 구독을 위해 useSyncExternalStore 훅이 권장되며, 브라우저 API(예: navigator.onLine) 구독에도 사용 가능합니다(ar.legacy.reactjs.org). (선택) 향후 리팩토링 시 useSyncExternalStore 적용을 검토하십시오.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 12c2da4 and b8e7839.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (6)
  • src/app/layout.tsx (2 hunks)
  • src/app/page.tsx (1 hunks)
  • src/app/reaction-test/page.tsx (1 hunks)
  • src/components/ClientHeader.tsx (1 hunks)
  • src/components/auth/SignupModal.tsx (5 hunks)
  • src/components/ui/Header.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-08T14:00:26.599Z
Learnt from: cl-o-lc
PR: The-CheckMate/CheckTime-FE#6
File: src/components/auth/SignupModal.tsx:40-63
Timestamp: 2025-08-08T14:00:26.599Z
Learning: Repo preference: In src/components/auth/SignupModal.tsx, enforcing a strict 8+ character password check in canSubmit is considered optional by the maintainer (cl-o-lc) and may be deferred; avoid blocking PRs on this point and consider aligning UI copy if necessary.

Applied to files:

  • src/components/auth/SignupModal.tsx
🧬 Code graph analysis (2)
src/components/ClientHeader.tsx (4)
src/components/ui/Header.tsx (1)
  • Header (23-102)
src/components/auth/LoginModal.tsx (1)
  • LoginModal (15-174)
src/components/auth/SignupModal.tsx (1)
  • SignupModal (16-252)
src/components/ui/ConfirmModal.tsx (1)
  • ConfirmModal (15-105)
src/app/layout.tsx (1)
src/components/ClientHeader.tsx (1)
  • ClientHeader (10-167)
🔇 Additional comments (10)
src/components/ui/Header.tsx (1)

58-63: 헤더 네비게이션 업데이트 확인됨

반응속도 게임 링크가 새로운 /reaction-test 라우트로 올바르게 연결되었습니다.

src/app/reaction-test/page.tsx (1)

78-80: 초기화 시 최고 기록 유지 확인

handleReset 함수가 기록을 초기화하지만 최고 기록(best)은 유지됩니다. 이것이 의도된 동작인지 확인이 필요합니다.

UI에서 "기록 초기화" 버튼이 최고 기록도 함께 초기화해야 하는지 확인해 주세요. 사용자 입장에서는 모든 기록이 초기화될 것으로 예상할 수 있습니다.

src/app/layout.tsx (1)

31-35: 전역 헤더 추가 확인

ClientHeader 컴포넌트가 전역적으로 추가되어 인증 상태 관리가 중앙화되었습니다. 구조적으로 깔끔한 개선입니다.

src/components/auth/SignupModal.tsx (1)

8-12: username 필드명 일관성 확인 필요

  • 백엔드 API 스펙 또는 테스트 POST 요청을 통해 실제 기대값이 소문자 username인지 검증
  • ClientHeader.tsx 등 API 호출부에서도 동일한 필드명(username)이 사용되는지 확인
src/components/ClientHeader.tsx (6)

1-9: 잘 작성된 컴포넌트 구조입니다

클라이언트 측 헤더 컴포넌트로서 필요한 의존성들을 적절히 import하고 있습니다. 'use client' 지시자를 사용해 클라이언트 컴포넌트임을 명확히 지정했습니다.


44-75: 로그인 API 호출 구현이 적절합니다

API 호출, 에러 처리, localStorage 저장 로직이 잘 구성되어 있습니다. 성공 시 모달을 닫기 위해 true를 반환하는 패턴도 적절합니다.


77-106: 회원가입 처리 로직이 올바릅니다

회원가입 성공 후 로그인 모달로 유도하는 UX 플로우가 적절합니다. 에러 처리도 잘 구현되어 있습니다.


108-118: 로그아웃 처리가 완전합니다

관련된 모든 localStorage 항목을 정리하고, 상태를 초기화한 후 홈페이지로 리다이렉션하는 로직이 적절합니다.


120-166: UI 렌더링과 모달 연동이 잘 구성되었습니다

인증 상태에 따른 조건부 렌더링, 모달 상태 관리, 그리고 모달 간 전환 로직이 모두 적절하게 구현되어 있습니다.


63-68: API 응답 필드 불일치 — 백엔드 응답 구조 확인 필요

ClientHeader의 로그인 처리부가 data.data.user.username을 사용합니다(src/components/ClientHeader.tsx:63–68) 반면 회원가입 요청은 body에 userName을 전송합니다(src/components/ClientHeader.tsx:89–94). 백엔드가 로그인 응답에 반환하는 필드명(username vs userName)을 확인하고 프론트 쪽 요청/응답 필드명을 일관되게 맞추거나 로그인 핸들러에서 올바른 필드를 사용하도록 수정하세요.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants