-
Notifications
You must be signed in to change notification settings - Fork 0
[feature] 사용자 반응속도 테스트 기능 구현 #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- `components/ClientHeader.tsx` 신규 생성 - 로그인/회원가입/로그아웃 로직을 내부에 통합 - Login, Signup, Confirm 모달 상태를 내부에서 관리 - Header에 isAuthed, userName, onLoginClick, onLogoutClick 전달
|
Caution Review failedThe pull request is closed. Walkthrough전역 레이아웃에 클라이언트 헤더를 추가했고 홈 페이지에서 인증 관련 상태/모달/로컬스토리지 토큰 처리를 제거했습니다. 신규 클라이언트 페이지로 반응속도 게임을 도입했고, 회원가입 모달의 onSubmit 페이로드 필드명을 Changes
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
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: 초기 상태 복귀
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (3)
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. Comment |
There was a problem hiding this 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 타입 지정
timerRef와startTsRef의 타입을 더 명확하게 지정하면 타입 안정성이 향상됩니다.- 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 함수명 불일치
userNamestate 변수명과setUsernamesetter 함수명이 일치하지 않습니다. 일관성을 위해 수정이 필요합니다.- 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컴포넌트의userNameprop이 선택적 타입인지 확인이 필요합니다.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
⛔ Files ignored due to path filters (1)
package-lock.jsonis 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)을 확인하고 프론트 쪽 요청/응답 필드명을 일관되게 맞추거나 로그인 핸들러에서 올바른 필드를 사용하도록 수정하세요.
📌 작업 내용
📸 스크린샷
📝 기타
Summary by CodeRabbit