-
Notifications
You must be signed in to change notification settings - Fork 0
20251114 #52 페이지 내부 바텀시트 개선 #53
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
The head ref may contain hidden characters: "20251114_#52_\uD398\uC774\uC9C0_\uB0B4\uBD80_\uBC14\uD140\uC2DC\uD2B8_\uAC1C\uC120"
Conversation
|
Caution Review failedThe pull request is closed. Walkthrough여러 파일에서 주로 포맷/주석/구성 재정렬이 적용되었고, BottomSheet는 포인터 드래그·ESC 바인딩·공개 prop 변화(isOpen/className 제거 등)를 포함해 리팩토링되었으며 VotePage의 searchParams 처리가 Promise(비동기)로 변경되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant VotePage
participant Router
Note right of VotePage `#DCEFFF`: searchParams가 Promise로 전달됨
Client->>VotePage: 요청 (searchParams: Promise)
VotePage->>VotePage: await searchParams
VotePage->>VotePage: const { participantId, username } = params
alt participantId 또는 username 누락
VotePage->>Router: 리다이렉트 처리
else
VotePage->>VotePage: 룸 정보 조회 및 렌더링 준비
VotePage->>Client: TimeGridVote 렌더링
end
sequenceDiagram
participant User
participant BottomSheet
participant PointerEvents
Note right of BottomSheet `#FFF1D6`: 초기화: 높이 재계산, 드래그 리셋
User->>BottomSheet: isOpen=true (시트 열기)
BottomSheet->>BottomSheet: calculateHeight, set heightPct
User->>PointerEvents: pointerdown on handle
PointerEvents->>BottomSheet: pointermove => 높이 업데이트
alt 최종 높이 < closeThreshold (예: 12vh)
PointerEvents->>BottomSheet: close() 호출
else 높이 < initialHeightPct
PointerEvents->>BottomSheet: snap to initialHeightPct
end
PointerEvents->>BottomSheet: pointerup/cancel => 이벤트 정리
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 분
Possibly related PRs
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 (1)
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: 2
🧹 Nitpick comments (5)
public/sw.js (1)
80-108: 오프라인 폴백 로직 개선, 단 미세한 개선 여지 있음오프라인 폴백을 외부 catch로 이동한 것은 좋은 개선입니다. 전체 흐름(캐시 조회 + 네트워크 요청)을 커버하게 되었습니다.
다만, 106번 라인의
caches.match('/')가 실패하면undefined를 반환할 수 있습니다. 더 견고한 폴백을 위해 다음과 같이 개선할 수 있습니다:.catch(() => { // 오프라인 시 기본 페이지 반환 if (event.request.destination === 'document') { - return caches.match('/'); + return caches.match('/').then(response => { + return response || new Response( + '<!DOCTYPE html><html><body><h1>오프라인</h1><p>네트워크 연결을 확인해주세요.</p></body></html>', + { headers: { 'Content-Type': 'text/html' } } + ); + }); } })src/app/meeting/[id]/vote/page.tsx (1)
12-25: Next.js 15 비동기 파라미터 마이그레이션 완료Next.js 15에서
searchParams가 비동기로 변경된 것에 맞춰 올바르게 구현되었습니다.Promise로 타입을 변경하고await로 값을 추출하는 패턴이 정확합니다.다만, TypeScript 컨벤션에 따라 인터페이스명을 PascalCase로 변경하는 것을 권장합니다:
-interface searchParams { +interface SearchParams { participantId?: string; username?: string; } export default async function VotePage({ params, searchParams, }: { params: Promise<{ id: string }>; - searchParams: Promise<searchParams>; + searchParams: Promise<SearchParams>; }): Promise<JSX.Element> {src/features/meeting/components/JoinParticipantForm.tsx (1)
13-19: 인터페이스 이름을 더 명확하게 변경하는 것을 권장합니다.인터페이스 이름을
JoinParticipantFormProps에서props로 변경했는데,props는 너무 일반적이며 TypeScript 컨벤션(PascalCase)을 따르지 않습니다. 가독성과 유지보수성을 위해 원래 이름을 유지하거나JoinParticipantFormProps로 되돌리는 것을 권장합니다.-interface props { +interface JoinParticipantFormProps { roomId: string; } export default function JoinParticipantForm({ roomId, -}: props): JSX.Element { +}: JoinParticipantFormProps): JSX.Element {src/features/meeting/components/SlotParticipantsSheet.tsx (2)
4-4: React import가 필요한지 확인하세요.
React를 import했지만 코드에서React.ReactNode나 다른 React 네임스페이스 멤버를 직접 사용하지 않습니다.JSX와useMemo만 사용되므로Reactimport는 불필요할 수 있습니다.-import React, { JSX, useMemo } from "react"; +import { JSX, useMemo } from "react";
10-24: 인터페이스 이름을 더 명확하게 변경하는 것을 권장합니다.인터페이스 이름을
props로 변경했는데, 이는 TypeScript 컨벤션(PascalCase)을 따르지 않으며 너무 일반적입니다.SlotParticipantsSheetProps같은 명확한 이름을 사용하는 것이 좋습니다.-interface props { +interface SlotParticipantsSheetProps { isOpen: boolean; onClose: () => void; roomInfo: RoomInfoResponse; date: string | null; timeSlot: string | null; } export default function SlotParticipantsSheet({ isOpen, onClose, roomInfo, date, timeSlot, -}: props): JSX.Element | null { +}: SlotParticipantsSheetProps): JSX.Element | null {
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (5)
public/file.svgis excluded by!**/*.svgpublic/globe.svgis excluded by!**/*.svgpublic/next.svgis excluded by!**/*.svgpublic/vercel.svgis excluded by!**/*.svgpublic/window.svgis excluded by!**/*.svg
📒 Files selected for processing (40)
.eslintrc.json(1 hunks).github/workflows/apk-build.yml(2 hunks).github/workflows/chuseok22-issue-helper.yml(1 hunks).github/workflows/sync-issue-labels.yaml(1 hunks)public/.well-known/assetlinks.json(1 hunks)public/browserconfig.xml(1 hunks)public/sw.js(4 hunks)src/app/create-meeting/page.tsx(1 hunks)src/app/error.tsx(1 hunks)src/app/join-meeting/page.tsx(1 hunks)src/app/layout.tsx(1 hunks)src/app/meeting/[id]/page.tsx(1 hunks)src/app/meeting/[id]/vote/page.tsx(2 hunks)src/app/page.tsx(1 hunks)src/app/privacy/page.tsx(1 hunks)src/components/BodySection.tsx(1 hunks)src/components/BottomSheet.tsx(3 hunks)src/components/BottomSheetProvider.tsx(2 hunks)src/components/Header.tsx(1 hunks)src/features/create-meeting/components/Calendar.tsx(2 hunks)src/features/create-meeting/hooks/useCalendar.ts(1 hunks)src/features/home/components/ActionCard.tsx(1 hunks)src/features/home/components/HelpButton.tsx(1 hunks)src/features/home/components/HelpModal.tsx(1 hunks)src/features/join-meeting/components/JoinCodeForm.tsx(1 hunks)src/features/meeting/components/CopyButton.tsx(1 hunks)src/features/meeting/components/JoinParticipantForm.tsx(2 hunks)src/features/meeting/components/JoinParticipantSheet.tsx(2 hunks)src/features/meeting/components/SlotParticipantsSheet.tsx(2 hunks)src/features/meeting/components/TimeGridView.tsx(1 hunks)src/features/meeting/components/slotParticipantsSheetHelper.ts(2 hunks)src/features/meeting/components/timeGridHelper.ts(1 hunks)src/lib/api/apiClient.ts(1 hunks)src/lib/api/apiServer.ts(1 hunks)src/lib/bff/proxy.ts(2 hunks)src/lib/errors/customError.ts(1 hunks)src/styles/base.css(1 hunks)src/styles/components.css(2 hunks)src/utils/dateUtils.ts(1 hunks)tsconfig.json(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (14)
src/features/home/components/HelpButton.tsx (1)
src/features/home/components/HelpModal.tsx (1)
HelpModal(11-129)
src/features/create-meeting/hooks/useCalendar.ts (1)
src/utils/dateUtils.ts (1)
isSameDate(2-6)
src/lib/bff/proxy.ts (1)
src/lib/bff/proxyTypes.ts (1)
ProxyConfig(9-18)
src/features/meeting/components/timeGridHelper.ts (1)
src/features/meeting/components/TimeGridVote.tsx (1)
SelectedMap(12-12)
src/app/create-meeting/page.tsx (3)
src/components/Header.tsx (1)
Header(11-41)src/components/BodySection.tsx (1)
BodySection(3-13)src/features/create-meeting/components/Calendar.tsx (1)
Calendar(13-113)
src/app/meeting/[id]/vote/page.tsx (4)
src/components/Header.tsx (1)
Header(11-41)src/components/BodySection.tsx (1)
BodySection(3-13)src/features/meeting/components/CopyButton.tsx (1)
CopyButton(15-56)src/features/meeting/components/TimeGridVote.tsx (1)
TimeGridVote(24-463)
src/features/meeting/components/slotParticipantsSheetHelper.ts (1)
src/features/meeting/types/apiTypes.ts (2)
RoomInfoResponse(17-25)DateAvailabilityResponse(12-15)
src/features/meeting/components/SlotParticipantsSheet.tsx (2)
src/features/meeting/types/apiTypes.ts (1)
RoomInfoResponse(17-25)src/components/BottomSheet.tsx (1)
BottomSheet(15-183)
src/app/join-meeting/page.tsx (3)
src/components/Header.tsx (1)
Header(11-41)src/components/BodySection.tsx (1)
BodySection(3-13)src/features/join-meeting/components/JoinCodeForm.tsx (1)
JoinCodeForm(10-72)
src/components/BottomSheet.tsx (1)
src/components/bottomSheetHelper.ts (1)
calculateHeight(1-3)
src/features/meeting/components/JoinParticipantSheet.tsx (2)
src/components/BottomSheet.tsx (1)
BottomSheet(15-183)src/features/meeting/components/JoinParticipantForm.tsx (1)
JoinParticipantForm(17-143)
src/app/meeting/[id]/page.tsx (9)
src/components/Header.tsx (1)
Header(11-41)src/components/BottomSheetProvider.tsx (1)
BottomSheetProvider(17-40)src/components/BodySection.tsx (1)
BodySection(3-13)src/features/meeting/components/CopyButton.tsx (1)
CopyButton(15-56)src/lib/types.ts (1)
ORIGIN_URL(12-12)src/utils/dateUtils.ts (2)
formatDateForDetailDisplay(45-53)toLocalDate(29-32)src/types/timeSlot.ts (1)
TIME_SLOT_MAP(1-34)src/features/meeting/components/JoinParticipantSheet.tsx (1)
JoinParticipantSheet(12-55)src/features/meeting/components/TimeGridView.tsx (1)
TimeGridView(20-101)
src/app/page.tsx (2)
src/features/home/components/ActionCard.tsx (1)
ActionCard(15-49)src/features/home/components/HelpButton.tsx (1)
HelpButton(7-44)
src/features/meeting/components/TimeGridView.tsx (1)
src/features/meeting/components/SlotParticipantsSheet.tsx (1)
SlotParticipantsSheet(18-130)
🔇 Additional comments (54)
src/lib/api/apiClient.ts (1)
6-9: 요청 메서드 서명 서식 변경 — 승인됨매개변수 목록의 들여쓰기만 조정되었으며, 동작이나 타입에 변화는 없습니다. 순수 포맷팅 개선입니다.
src/lib/api/apiServer.ts (1)
16-19: 요청 메서드 서명 서식 변경 — 승인됨매개변수 목록의 들여쓰기만 조정되었으며, 동작이나 타입에 변화는 없습니다.
apiClient.ts와 일관된 서식으로 통일되었습니다.public/.well-known/assetlinks.json (1)
3-5: JSON 형식 정리 - 기능상 변화 없음.
relation배열의 형식만 변경되었으며, 의미있는 콘텐츠는 동일합니다. Google Digital Asset Links 사양상 유효한 변경입니다.public/browserconfig.xml (1)
5-5: XML 요소 순서 정리 - 기능상 변화 없음.Microsoft 공식 문서의 browserconfig.xml 예제들에서도 TileColor와 로고 요소들의 순서가 유연하게 나타나 이러한 요소 재배치는 기능에 영향을 주지 않습니다.
Also applies to: 8-8
src/utils/dateUtils.ts (1)
3-5: 포맷팅 변경만 반영됨.
isSameDate함수의 반환문 들여쓰기가 개선되었습니다. 기능상 변화는 없습니다.src/features/create-meeting/hooks/useCalendar.ts (2)
25-26: 포맷팅 개선: findIndex 콜백 들여쓰기.들여쓰기만 정렬되었으며, 기능상 변화는 없습니다.
1-59: PR 제목과 변경 내용 불일치 확인.PR 제목은 "페이지 내부 바텀시트 개선"이지만, 실제 변경사항은
dateUtils.ts와useCalendar.ts의 순수 포맷팅(들여쓰기)입니다. 바텀시트 구현 자체에 대한 변경이 보이지 않습니다. PR 설명에서 변경 사항을 명확히 기술해주기 바랍니다.또한 PR 체크리스트에서 "Manual testing completed"와 "Test code completed"가 모두 미완료 상태입니다. 병합 전에 이를 완료해주시기 바랍니다.
src/lib/bff/proxy.ts (3)
13-15: 매개변수 재정렬 형식 변경은 적절합니다.함수 시그니처의 매개변수들이 일관된 들여쓰기로 재포맷팅되었으며, 의미론적 변화는 없습니다. 코드 스타일 통일 관점에서 긍정적입니다.
107-113: 에러 응답 객체 재포맷팅은 가독성을 개선합니다.500 에러 응답의 객체 리터럴이 다중 라인으로 재포맷팅되어 더 명확합니다. 응답 내용 및 상태코드는 동일하게 유지되어 의미론적 변화가 없습니다.
1-116: PR 범위와 파일 내용 간 스코프 불일치 확인PR 제목은 "바텀시트 개선"을 언급하지만, 이 파일(
proxy.ts)은 BFF 프록시 유틸리티입니다. 현재 변경사항들은 순수 포맷팅 조정(들여쓰기, 줄바꿈)만 포함하며, 바텀시트 또는 UI 컴포넌트와 직접적인 관련이 없습니다.AI 요약에 따르면 이러한 포맷팅 변경들은 "프로젝트 전역에 걸친 광범위한 포맷팅 조정" 일부인 것으로 보입니다. 코드 정확성에 영향을 주지는 않으나, PR 설명을 확인하여 의도적인 범위 확대인지 확인하시기 바랍니다.
PR 설명에서 구체적인 변경사항 설명이 누락되어 있습니다. 이 파일이 포함된 의도와 모든 변경사항을 정리한 명확한 설명을 추가해 주시기 바랍니다.
public/sw.js (5)
1-155: PR 제목과 실제 변경 내용 간 불일치PR 제목은 "페이지 내부 바텀시트 개선"이지만, 실제 변경사항은 서비스 워커 파일의 Promise 체인 구조 개선입니다. PR 설명에서 실제 변경 내용에 대한 구체적인 설명을 추가해주세요.
16-47: 코드 가독성 개선Promise 체인의 들여쓰기가 일관되게 개선되어 코드 가독성이 향상되었습니다.
54-56: 명시적 반환문 추가GET 요청이 아닌 경우 명시적으로
return하여 제어 흐름이 더 명확해졌습니다.
61-73: LGTM!API 요청 실패 시 적절한 503 응답을 반환하는 로직이 유지되고 있습니다.
114-116: 방어적 코딩 개선이벤트 데이터가 없을 때 조기 반환하여 불필요한 처리를 방지합니다.
src/features/meeting/components/timeGridHelper.ts (1)
30-36: 포매팅 변경 확인 완료함수 파라미터의 들여쓰기만 변경되었으며, 로직과 시그니처는 동일합니다.
src/components/BodySection.tsx (1)
9-11: 포매팅 변경 확인 완료JSX 들여쓰기만 조정되었으며, 렌더링 결과는 동일합니다.
src/lib/errors/customError.ts (1)
8-12: 포매팅 변경 확인 완료생성자 파라미터의 들여쓰기만 변경되었으며, 동작은 동일합니다.
src/app/create-meeting/page.tsx (1)
54-105: 포매팅 변경 및 CSS 유틸리티 클래스 적용 확인JSX 구조가 재정렬되었으며, 새로 추가된 CSS 유틸리티 클래스(
main-container,input-primary)가 적절히 사용되었습니다. 컴포넌트 로직은 변경되지 않았습니다..github/workflows/sync-issue-labels.yaml (1)
13-14: YAML 들여쓰기 확인 완료
tags-ignore하위 리스트 항목의 들여쓰기가 올바르게 적용되었습니다..github/workflows/chuseok22-issue-helper.yml (1)
5-5: 포매팅 변경 확인 완료배열 내부 공백이 추가되었으나 동작에는 영향이 없습니다.
src/app/error.tsx (1)
10-19: 포매팅 변경 확인 완료에러 페이지 JSX의 들여쓰기만 조정되었으며, 렌더링 결과와 이벤트 핸들러는 동일합니다.
src/styles/components.css (3)
10-12: 새로운 input 스타일 클래스 추가 확인재사용 가능한 input 스타일 클래스가 추가되었습니다. 프로젝트 전반에서 일관된 input 스타일링을 위해 좋은 개선입니다.
21-23: 포매팅 변경 확인 완료스크롤바 숨김 스타일의 들여쓰기가 조정되었으며, 동작은 동일합니다.
6-8: 유틸리티 클래스 추가 확인됨 - 추가 적용 제안
.main-container클래스가src/styles/components.css에 올바르게 정의되어 있고, 현재 세 개의 주요 페이지(join-meeting,meeting/[id],create-meeting)에 적절하게 적용되어 있습니다.검색 결과
src/app/page.tsx라인 25의className="flex flex-col w-full gap-8 px-4 lg:px-8"은 유사한 패턴을 보이므로, 요구사항에 맞는 경우main-container적용을 고려할 수 있습니다. 단,src/components/BodySection.tsx나src/app/error.tsx같은 다른 컴포넌트들은 서로 다른 패딩(px-6,p-4) 또는 추가 스타일(배경색, 높이 제약)을 가지고 있어 현재 상태 유지가 적절합니다.src/features/create-meeting/components/Calendar.tsx (1)
1-113: LGTM! 일관된 코드 포맷팅 개선Calendar 컴포넌트의 JSX 구조를 일관되게 재정렬한 변경사항입니다. 모든 기능과 로직은 그대로 유지되고 있습니다.
src/styles/base.css (1)
3-5: LGTM! 브라우저 호환성 개선
height: 100%;를 fallback으로 추가하여dvh단위를 지원하지 않는 브라우저에서도 정상적으로 동작하도록 개선되었습니다.tsconfig.json (1)
1-40: LGTM! 가독성 개선TypeScript 설정의 가독성을 위한 포맷팅 변경입니다. 설정 내용은 동일하게 유지됩니다.
.github/workflows/apk-build.yml (1)
5-5: LGTM! YAML 포맷 정규화워크플로우 동작에는 영향 없는 포맷팅 변경입니다.
src/app/privacy/page.tsx (1)
1-169: LGTM! 일관된 JSX 포맷팅개인정보 처리방침 페이지의 JSX 구조를 일관되게 재정렬한 변경사항입니다. 모든 콘텐츠와 기능은 동일하게 유지됩니다.
.eslintrc.json (1)
1-54: LGTM! 가독성 및 문서화 개선ESLint 설정에 한국어 주석을 추가하고 포맷을 개선했습니다. 실제 린팅 규칙은 변경되지 않았습니다.
src/features/home/components/ActionCard.tsx (1)
26-47: LGTM! 레이아웃 구조 개선ActionCard의 레이아웃이 재구성되었습니다. 아이콘과 텍스트를 별도 컬럼으로 분리하고 버튼을 하단으로 이동하여 시각적 계층이 개선되었습니다. 모든 props와 기능은 동일하게 유지됩니다.
src/app/meeting/[id]/vote/page.tsx (1)
34-72: LGTM! 일관된 JSX 포맷팅투표 페이지의 JSX 구조를 일관되게 재정렬한 변경사항입니다. 모든 기능과 로직은 동일하게 유지됩니다.
src/features/join-meeting/components/JoinCodeForm.tsx (1)
38-70: 포매팅 개선으로 보임 - 함수 로직은 변경 없음폼 구조의 들여쓰기와 줄 바꿈만 조정되었으며, JSX 계층 구조, 이벤트 핸들러, 상태 관리는 모두 동일합니다.
src/features/meeting/components/CopyButton.tsx (1)
41-53: 포매팅 정리만 이루어짐버튼 JSX의 들여쓰기만 조정되었으며, 클래스명, 이벤트 핸들러, 렌더링 로직은 변경되지 않았습니다.
src/app/layout.tsx (1)
71-79: 레이아웃 들여쓰기 정리만 해당body 및 div 래퍼 요소의 들여쓰기만 조정되었으며, 클래스명과 계층 구조는 유지됩니다.
src/features/meeting/components/slotParticipantsSheetHelper.ts (1)
7-20: 함수 매개변수 들여쓰기 정리함수 매개변수 목록의 들여쓰기만 조정되었으며, 함수 서명과 로직은 변경되지 않았습니다.
src/components/Header.tsx (1)
25-39: 헤더 JSX 들여쓰기 정리헤더 요소의 들여쓰기와 줄 바꿈만 조정되었으며, 접근성 속성, 이벤트 핸들러, 렌더링 로직은 유지됩니다.
src/app/join-meeting/page.tsx (1)
7-18: 페이지 레이아웃 들여쓰기 정리JoinMeetingPage의 JSX 구조 들여쓰기만 조정되었으며, 컴포넌트 사용과 프로퍼티는 변경되지 않았습니다.
src/features/home/components/HelpButton.tsx (1)
24-42: 헬프 버튼 JSX 들여쓰기 정리버튼과 모달 요소의 들여쓰기만 조정되었으며, 상태 관리, 이벤트 핸들러, 접근성 속성은 유지됩니다.
src/app/meeting/[id]/page.tsx (1)
28-101: 주요 변경사항: 레이아웃 구조화 및 비동기 params 처리다음 사항을 확인해주세요:
Next.js 15 비동기 params 처리 (라인 16-21):
params: Promise<{ id: string }>로 선언하고await params로 처리하는 것은 Next.js 15의 올바른 패턴입니다.TimeGridView와 SlotParticipantsSheet 통합: 제공된 relevant_code_snippets에서 TimeGridView는 SlotParticipantsSheet에
isOpen프로퍼티를 전달합니다 (라인 96). 이것이 SlotParticipantsSheet의 프로퍼티 이름과 일치하는지 확인이 필요합니다.BottomSheetProvider 위치 (라인 30): main 요소를 감싸도록 올바르게 위치했습니다.
다음을 확인해주세요:
- SlotParticipantsSheet 컴포넌트가
isOpen프로퍼티를 받도록 업데이트되었는지 확인- TimeGridView에서 SlotParticipantsSheet로 전달되는 모든 프로퍼티가 정의된 인터페이스와 일치하는지 확인
src/components/BottomSheetProvider.tsx (1)
32-36: 컨텍스트 값 메모이제이션 적용이 적절합니다.
useMemo를 사용하여 컨텍스트 값을 메모이제이션함으로써activeId가 변경될 때만 새 객체가 생성되도록 최적화했습니다. 이는 하위 컴포넌트의 불필요한 리렌더링을 방지합니다.src/app/page.tsx (1)
8-52: 레이아웃 구조 개선이 적절합니다.페이지 레이아웃을 정리하고 HelpButton을 우하단 고정 위치로 배치한 것은 사용자 경험 측면에서 적절한 개선입니다.
src/features/meeting/components/JoinParticipantSheet.tsx (2)
34-41: 모달 오버레이 패턴 적용이 적절합니다.참여 시트에 모달 오버레이를 추가하여 사용자가 폼 작성에 집중할 수 있도록 개선했습니다.
backdrop-blur와 어두운 배경이 적절히 적용되었습니다.
46-47: 바텀시트 높이 증가를 확인하세요.
initialHeightPct를 50에서 60으로,maxHeightPct를 70에서 80으로 증가시켰습니다. 폼 콘텐츠가 더 넓은 화면에서도 잘 표시되는지 다양한 기기에서 테스트하여 확인하시기 바랍니다.src/features/meeting/components/TimeGridView.tsx (1)
89-98: Props 이름 변경이 일관성을 개선합니다.
SlotParticipantsSheet의 prop 이름을open에서isOpen으로 변경하여BottomSheet컴포넌트의 API와 일관성을 유지했습니다.src/features/home/components/HelpModal.tsx (1)
22-35: 모달 클릭 처리 개선이 적절합니다.외부 컨테이너에
onClick={onClose}를 배치하고 내부 콘텐츠에서 이벤트 전파를 중단하는 패턴은 모달 UX의 표준 구현입니다. 반응형 사이징 추가도 모바일 경험을 개선합니다.src/features/meeting/components/SlotParticipantsSheet.tsx (1)
57-57: 초기 높이 증가를 확인하세요.
initialHeightPct를 25에서 40으로 증가시켰습니다. 이는 사용자 경험을 개선할 수 있지만, 작은 화면에서 콘텐츠가 과도하게 화면을 차지하지 않는지 테스트하여 확인하시기 바랍니다.src/components/BottomSheet.tsx (6)
35-41: 높이 초기화 로직이 적절합니다.
isOpen이 변경될 때마다 높이를 초기값으로 리셋하는 것은 이전 상태가 다음 열림에 영향을 주지 않도록 하는 좋은 패턴입니다.
43-55: ESC 키 핸들링 개선이 적절합니다.Effect를 사용하여 ESC 키 리스너를 관리하는 것은 깔끔한 분리를 제공하며,
isOpen이 false일 때 리스너를 추가하지 않아 성능도 개선됩니다.
66-73: 전역 포인터 이벤트 처리가 우수합니다.드래그 중 포인터가 핸들 영역을 벗어나도 계속 추적할 수 있도록 전역 리스너를 사용한 것은 모바일 환경에서 드래그 UX를 크게 개선합니다.
preventDefault()로 스크롤 충돌도 방지했습니다.
86-95: 드래그 종료 임계값 로직을 검증하세요.12vh 미만에서 닫고,
initialHeightPct미만에서 초기 높이로 스냅하는 로직이 구현되었습니다. 다양한 기기와 콘텐츠 높이에서 이 임계값들이 적절하게 동작하는지 테스트하여 확인하시기 바랍니다.
135-181: 바텀시트 렌더링 구조 개선이 우수합니다.새로운 렌더링 구조는 다음과 같은 개선사항을 제공합니다:
- 외부 컨테이너의
pointer-events-none과 내부 시트의pointer-events-auto로 적절한 이벤트 처리- 분리된 드래그 핸들 영역으로 명확한 상호작용 영역 제공
overflow-y-auto와overscroll-y-contain으로 스크롤 동작 개선transform-gpu로 애니메이션 성능 최적화
7-21: Props 인터페이스 단순화가 적절하고 안전합니다.
classNameprop 제거가 검증되었습니다. 기존 코드에서 BottomSheet에 className prop을 전달하는 사용처가 없으므로, 이 리팩토링은 컴포넌트 API를 단순화하고 책임을 명확히 하는 좋은 변경입니다:
src/features/meeting/components/JoinParticipantSheet.tsx(43-50): className 없음src/features/meeting/components/SlotParticipantsSheet.tsx(54-58): className 없음모든 호출이
isOpen,onClose,initialHeightPct,maxHeightPct프로퍼티만 사용하므로 변경사항은 안전합니다.
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: 1
♻️ Duplicate comments (1)
src/components/BottomSheet.tsx (1)
138-140:aria-modal속성을 동적으로 제어할 수 있도록 수정하세요.
aria-modal="true"로 하드코딩되어 있지만, 이전 리뷰에서 지적된 대로 오버레이가 있는 경우(JoinParticipantSheet)와 없는 경우(SlotParticipantsSheet)를 구분해야 합니다. 오버레이 없이 백그라운드와 상호작용이 가능한 경우aria-modal="false"가 의미적으로 올바릅니다.이전 리뷰의 제안대로
ariaModalprop을 추가하세요:interface Props { isOpen: boolean; onClose: () => void; initialHeightPct?: number; maxHeightPct?: number; + ariaModal?: boolean; children: React.ReactNode; } export default function BottomSheet({ isOpen, onClose, initialHeightPct = 25, maxHeightPct = 70, + ariaModal = false, children }: Props): JSX.Element | null { // ... <div ref={sheetRef} role="dialog" - aria-modal="true" + aria-modal={String(ariaModal)} aria-label="바텀시트"그런 다음
JoinParticipantSheet에서ariaModal={true}를 전달하세요.
🧹 Nitpick comments (2)
src/features/meeting/components/SlotParticipantsSheet.tsx (1)
10-16: 인터페이스 이름을 PascalCase로 변경하세요.TypeScript 명명 규칙에 따라 인터페이스 이름은 대문자로 시작해야 합니다.
다음 diff를 적용하세요:
-interface props { +interface Props { isOpen: boolean; onClose: () => void; roomInfo: RoomInfoResponse; date: string | null; timeSlot: string | null; }그리고 함수 시그니처도 업데이트하세요:
export default function SlotParticipantsSheet({ isOpen, onClose, roomInfo, date, timeSlot, -}: props): JSX.Element | null { +}: Props): JSX.Element | null {src/components/BottomSheet.tsx (1)
7-13: 인터페이스 이름을 PascalCase로 변경하세요.TypeScript 명명 규칙에 따라 인터페이스 이름은 대문자로 시작해야 합니다.
다음 diff를 적용하세요:
-interface props { +interface Props { isOpen: boolean; onClose: () => void; initialHeightPct?: number; maxHeightPct?: number; children: React.ReactNode; }그리고 함수 시그니처도 업데이트하세요:
export default function BottomSheet({ isOpen, onClose, initialHeightPct = 25, maxHeightPct = 70, children -}: props): JSX.Element | null { +}: Props): JSX.Element | null {
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/components/BottomSheet.tsx(3 hunks)src/features/meeting/components/SlotParticipantsSheet.tsx(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/features/meeting/components/SlotParticipantsSheet.tsx (2)
src/features/meeting/types/apiTypes.ts (1)
RoomInfoResponse(17-25)src/components/BottomSheet.tsx (1)
BottomSheet(15-183)
src/components/BottomSheet.tsx (1)
src/components/bottomSheetHelper.ts (1)
calculateHeight(1-3)
🔇 Additional comments (3)
src/features/meeting/components/SlotParticipantsSheet.tsx (1)
54-59: 변경 사항이 적절합니다.
isOpenprop으로의 이름 변경과initialHeightPct를 40으로 증가시킨 것은 일관성과 사용자 경험을 개선합니다.src/components/BottomSheet.tsx (2)
35-41: 시트가 열릴 때 높이를 초기화하는 로직이 잘 구현되었습니다.
isOpen이true가 될 때 높이와 드래그 상태를 초기화하는 것은 사용자 경험을 개선합니다.
43-55: ESC 키 처리 개선이 적절합니다.
isOpen이true일 때만 ESC 리스너를 등록하도록 변경한 것은 불필요한 이벤트 처리를 방지하고 메모리 효율성을 개선합니다.
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 (1)
src/app/layout.tsx (1)
32-33: 환경 변수 사용을 고려해보세요.프로덕션 URL을 하드코딩하는 대신 환경 변수를 사용하는 것이 좋습니다. 이렇게 하면 개발/스테이징/프로덕션 환경에서 유연하게 대응할 수 있습니다.
다음과 같이 수정할 수 있습니다:
-const SITE_URL = "https://meet.chuseok22.com" +const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || "https://meet.chuseok22.com"그리고
.env.local파일에 다음을 추가하세요:NEXT_PUBLIC_SITE_URL=http://localhost:3000
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/app/layout.tsx(2 hunks)
🔇 Additional comments (1)
src/app/layout.tsx (1)
35-38: LGTM!
metadataBase설정과 메타데이터 업데이트가 올바르게 적용되었습니다. 이중 언어 설명은 SEO와 국제 사용자 지원에 도움이 됩니다.
✨ 변경 사항
✅ 테스트
Summary by CodeRabbit
릴리스 노트
New Features
Bug Fixes
Style
Refactor