Conversation
- 비로그인 현황 조회 API 연동 및 UI 작업 - 랜덤 컬러 배정 시스템 개선
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Walkthrough참가자 색상 처리를 통합하고, 게스트 미팅 상태 조회 기능을 추가하며, 색상 생성 로직을 결정론적 팔레트 기반으로 변경하고, 참가자 데이터 병합 로직을 재구성했습니다. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Tip Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord. 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.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
app/result/[id]/page.tsx (1)
136-137:⚠️ Potential issue | 🔴 Critical
bg-gray-4로 되돌려야 합니다.
getLineColor함수의 기본 반환값이bg-gray-400으로 설정되어 있으나, 프로젝트 전반에서 일관되게 사용되는 커스텀 그레이 색상은bg-gray-4입니다. 다른 컴포넌트들(app/meeting/[id]/page.tsx, app/create/page.tsx, components/join/joinForm.tsx, components/modal/feedbackModal.tsx)에서bg-gray-4를 기본 비활성화 상태 색상으로 사용하고 있으므로, 이 부분도 동일하게bg-gray-4로 변경되어야 하는 일관성 문제입니다.
🧹 Nitpick comments (6)
app/recommend/page.tsx (1)
32-83:useMemo내부에서localStorage.setItem호출은 기존 코드이지만, 부수효과(side effect) 주의가 필요합니다.
meetingType과defaultCategoryuseMemo블록 내부에서localStorage.setItem을 호출하고 있습니다.useMemo는 순수 계산용이므로 부수효과는useEffect에서 처리하는 것이 React 권장 패턴입니다. 이번 PR의 변경 범위는 아니지만, 향후 리팩토링 시 개선을 고려해 주세요.lib/color.ts (2)
28-37:Math.abs(hash)가 정수 오버플로 시 정확하지 않을 수 있습니다.DJB2 해시 루프에서
(hash << 5)는 32비트 정수로 자르지만, 이후+ hash에서hash는 이전 반복의 전체 값(32비트 이상 가능)을 사용합니다. 반복이 누적되면hash가Number.MAX_SAFE_INTEGER를 초과하여 정밀도 손실이 발생할 수 있습니다. 일반적인 이름+모임ID 길이에서는 문제 없지만, 안전을 위해 매 반복마다 비트 마스킹을 적용하는 것을 권장합니다.🔧 비트 마스킹을 통한 오버플로 방지
let hash = 5381; for (let i = 0; i < key.length; i++) { - hash = (hash << 5) + hash + key.charCodeAt(i); + hash = ((hash << 5) + hash + key.charCodeAt(i)) | 0; }
| 0연산은 매 반복마다 결과를 32비트 정수로 잘라 오버플로를 방지하고, 표준 DJB2 구현과 동일한 동작을 보장합니다.
1-22: 팔레트 크기 20은 참여자 수가 많을 경우 색상 충돌 가능성이 있습니다.20개 팔레트에서 해시 기반으로 선택하므로, 참여자 수가 5명만 되어도 약 50% 확률로 2명 이상이 같은 색상을 받게 됩니다 (Birthday Problem). 현재 모임 규모에서 허용 가능한 수준인지 확인이 필요합니다. 만약 시각적 구분이 중요하다면, 충돌 회피 로직(이미 할당된 색상을 건너뛰는 방식)을 고려할 수 있습니다.
components/join/joinForm.tsx (2)
138-159: 참여자 목록에서getRandomHexColor가 참여자당 2번 호출됩니다.각 참여자에 대해
getRandomHexColor(p.userName, meetingId)가 배경색(Line 145)과 아바타(Line 149)에서 각각 호출됩니다. 함수 자체는 가볍지만, 결과를 변수에 저장하면 가독성과 일관성이 개선됩니다.♻️ 색상 결과를 변수로 추출
meetingInfo.participants.map((p, index) => { + const color = getRandomHexColor(p.userName, meetingId); return ( <div key={index} className="flex items-center gap-2 rounded-full py-1 pr-3 pl-1" - style={{ backgroundColor: `${getRandomHexColor(p.userName, meetingId)}33` }} + style={{ backgroundColor: `${color}33` }} > <div className="flex h-6 w-6 items-center justify-center rounded-full text-[10px] font-medium text-white" - style={{ backgroundColor: getRandomHexColor(p.userName, meetingId) }} + style={{ backgroundColor: color }} >
85-89: 에러 핸들링에서error: any타입 사용.
catch (error: any)대신 더 안전한 타입 처리를 권장합니다. 현재는error.data와error.response?.data에 접근하고 있는데,error의 실제 타입에 따라 런타임 에러가 발생할 수 있습니다. 이 부분은 기존 코드일 수 있으나, 에러 메시지 추출 로직 변경과 함께 개선할 수 있는 부분입니다.app/meeting/[id]/page.tsx (1)
158-186:useMemo내부에서 객체 직접 변이(mutation)는 코드 스멜입니다.Line 179-183에서
myParticipant의 속성을 직접 변경하고 있습니다..map()이 새 객체를 생성하므로 현재는 동작하지만,useMemo내에서의 직접 변이는 React의 불변성 원칙과 어긋나며 향후 리팩토링 시 버그의 원인이 될 수 있습니다.♻️ 스프레드 연산자로 불변성 유지
const myParticipant = participantsWithColor.find((p) => p.name === myName); const others = participantsWithColor.filter((p) => p.name !== myName); - if (myParticipant && selectedStation) { - const info = STATION_DATA.find((s) => s.name === selectedStation); - if (info) { - myParticipant.station = info.name; - myParticipant.line = info.line; - myParticipant.latitude = info.latitude; - myParticipant.longitude = info.longitude; - } - } - - return myParticipant ? [myParticipant, ...others] : others; + if (myParticipant && selectedStation) { + const info = STATION_DATA.find((s) => s.name === selectedStation); + if (info) { + const updatedMe = { + ...myParticipant, + station: info.name, + line: info.line, + latitude: info.latitude, + longitude: info.longitude, + }; + return [updatedMe, ...others]; + } + } + + return myParticipant ? [myParticipant, ...others] : others;
🚀 feat: 비로그인 모임 현황 조회 API 연동
📝 변경사항
✅ 체크리스트
📸 스크린샷
💬 리뷰어 전달사항
Summary by CodeRabbit
릴리스 노트
새로운 기능
개선 사항