Skip to content

[BOM-1172] refactor: 챌린지 코멘트 날짜 필터 UI 개선#291

Open
JeLee-river wants to merge 15 commits into
devfrom
BOM-1172-챌린지-코멘트-ui-개선

Hidden character warning

The head ref may contain hidden characters: "BOM-1172-\ucc4c\ub9b0\uc9c0-\ucf54\uba58\ud2b8-ui-\uac1c\uc120"
Open

[BOM-1172] refactor: 챌린지 코멘트 날짜 필터 UI 개선#291
JeLee-river wants to merge 15 commits into
devfrom
BOM-1172-챌린지-코멘트-ui-개선

Conversation

@JeLee-river

@JeLee-river JeLee-river commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

📌 What

  • 챌린지 코멘트 날짜 필터를 모바일/PC UI로 분리
  • PC 날짜 필터에 좌우 스크롤 탐색 추가
  • 챌린지 코멘트 날짜 로직 테스트 추가
2026-07-07.5.22.45.mov

❓ Why

  • PC의 날짜 탐색 UX 개선 목적 (기능 개선)
  • 날짜 로직의 일관된 검증 목적 (테스트)

🔧 How

기능 / 도메인 코드 리팩토링

  • 기존 DateFilter를 MobileDateFilter, PCDateFilter, DateTab 구조로 분리 (컴포넌트 분리)
  • useDateFilterScroll 훅을 추가해 PC 날짜 필터의 좌우 스크롤 가능 여부와 스크롤 동작을 관리
  • 챌린지 날짜 목록에서 오늘 이후 날짜를 제외하도록 useChallengeCommentDates 로직 정리
  • 기존 useDateFilter, getDisplayDates, 전역 isToday 유틸 제거
  • CommentCardSkeleton 추가 및 챌린지 상세/코멘트 MSW 응답 데이터 보강

날짜 정책을 테스트로 고정

  • 날짜 로직을 msw로 회귀 테스트를 하기 번거로움을 느끼고 테스트 코드를 추가했습니다.

    • mock 데이터를 매번 수정해야 하고, 직접 실행해서 테스트 해야하는 단점이 있음
  • 날짜 로직의 현재 날짜(오늘)을 특정 시점으로 고정한 상태에서, 주말, 자정, 챌린지 기간 경곗값 테스트를 추가했습니다.

    • 오늘 날짜는 테스트 실행 시점마다 달라지고 날짜 로직 계산에 영향을 주는 점을 고려하여 특정 시점으로 고정함
    테스트 대상 시간 제어 방식
    utils/date.test.ts 날짜 유틸 (범위 생성, 주말 필터링, 비교) 고정 날짜 입력
    hooks/useChallengeCommentDates.test.ts 날짜 필터 정책 jest.useFakeTimers() + setSystemTime()
    components/DateFilter/MobileDateFilter.test.tsx 필터 UI 렌더링 today prop 주입
    • 컴포넌트가 현재 날짜를 내부에서 계산하지 않고 prop으로 주입받도록 분리해, 시간을 제어할 수 있는 테스트 단위로 만들었습니다.
    • 테스트 환경 설정 추가
      • @babel/preset-react(JSX)
      • jest moduleNameMapper(@/ 별칭)

👀 Review Point

  • 모바일/PC에서 날짜 필터 레이아웃과 오늘 탭 노출 방식이 의도대로 동작하는지 확인
  • PC 날짜 필터 좌우 버튼의 disabled 상태와 스크롤 이동이 정상인지 확인
  • 챌린지 시작일/휴식일/오늘 이후 날짜 선택 가능 여부에 회귀가 없는지 확인
  • DateFilter 폴더 이동 후 import 경로가 실제 파일 위치와 일치하는지 확인
  • 테스트에 기술된 날짜 필터 정책이 기획 의도와 일치하는지
    • 유효한 챌린지 날짜(기간 내 평일)만 필터로 노출
    • 오늘이 기간 내 평일이면 '오늘' 라벨로 표시되고 선택된 상태
    • 오늘이 주말이면 직전 평일이 마지막 필터이자 선택된 상태
    • 챌린지 종료 후에는 마지막 챌린지 날짜가 선택된 상태

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

날짜 필터의 스크롤링 기능을 관리하는 훅입니다.

Comment on lines +15 to +24
const updateCanScroll = useCallback(() => {
const filterContainer = scrollRef.current;
if (!filterContainer) return;

setCanScrollLeft(filterContainer.scrollLeft > 0);
setCanScrollRight(
filterContainer.scrollLeft + filterContainer.clientWidth <
filterContainer.scrollWidth - 1,
);
}, []);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

필터의 x축 스크롤의 위치를 계산해 왼쪽(canScrollLeft), 오른쪽(canScrollRight) 스크롤링이 가능한지 업데이트 해줍니다.

PC에서 스크롤이 양쪽 끝까지 이동한 경우, 필터의 <, > 버튼을 비활성화하기 위해 추가한 기능입니다.

@jaeyoung-kwon jaeyoung-kwon left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🤖 PR Review

⚠️ 수정이 필요한 리뷰 코멘트가 있습니다.

챌린지 코멘트 페이지에 초기 선택 날짜(initialSelectedDate) 로직을 추가했지만, 실제 댓글 데이터를 가져오는 useCommentsPagination 호출에는 새 activeDate 대신 여전히 null일 수 있는 selectedDate를 그대로 넘기고 있어 타입 체크가 깨지고, 첫 진입 시 화면에 표시된 날짜와 실제로 조회되는 댓글 날짜가 어긋납니다.

🚨 1 Critical · ⚠️ 0 Major · 📝 0 Minor

수정 필요

  • web/src/routes/_bombom/_main/challenge/$challengeId/comments.tsx:73 — useCommentsPagination에 activeDate 대신 null 가능한 selectedDate 전달 (인라인 코멘트 참조).
📋 검증 과정
  • Claude structured review 결과 중 확신도가 있는 항목만 정리했습니다.
  • Critical/Major는 inline comment로 게시하고, Minor는 참고 항목으로 summary에 포함합니다.
  • 자동 생성된 OpenAPI 타입 선언 파일과 lock 파일은 리뷰 대상에서 제외합니다.

🤖 Claude PR Review


Generated by Claude Code

Comment on lines 73 to 77
const { baseQueryParams, changePage, page, resetPage } =
useCommentsPagination({
challengeId: Number(challengeId),
selectedDate,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🚨 [Critical] useCommentsPagination에 activeDate 대신 null 가능한 selectedDate 전달

comments.tsx:71에서 const activeDate = selectedDate ?? initialSelectedDate;로 화면 표시/휴식일 판정용 날짜를 계산해두고, isFirstDay(activeDate)/isChallengeDay(activeDate)/DateFilterselectedDate prop에는 이 값을 쓰지만, 정작 useCommentsPagination({ challengeId, selectedDate }) (76행)에는 원본 selectedDate state를 그대로 넘기고 있습니다. selectedDateuseState<string | null>(null)로 초기화되어 사용자가 탭을 클릭하기 전까지 null입니다.

결과적으로:

  1. useCommentsPagination의 파라미터 타입은 selectedDate: string인데 string | null이 전달되어 tsc --noEmit이 TS2322로 실패합니다 (실제로 재현: error TS2322: Type 'string | null' is not assignable to type 'string'. at comments.tsx:76:7).
  2. 타입 에러를 무시하고 런타임만 보면, 페이지 최초 진입 시 날짜 필터 UI는 activeDate(=initialSelectedDate, 챌린지 마지막 유효 날짜)가 선택된 것으로 보이는데, 실제 댓글 목록은 baseQueryParams.start/end = null로 요청되어 화면에 표시된 날짜와 실제로 불러오는 댓글의 날짜가 어긋납니다 (또는 API가 null 파라미터를 예상치 못한 방식으로 처리).

selectedDate 자리를 activeDate로 교체해야 의도한 동작(마지막 유효 날짜가 최초 선택 + 그 날짜로 댓글 조회)이 맞습니다.

Claude 검증: 변경 diff의 web/src/routes/_bombom/_main/challenge/$challengeId/comments.tsx:73-77 기준으로 확인했습니다. 실제 코드와 다르면 이 코멘트는 무시해 주세요. (confidence 0.95).

수정 제안:
이 finding이 여전히 유효한지 먼저 확인한 뒤, 관련 코드만 최소 범위로 수정하고 필요한 검증을 실행해 주세요.


Generated by Claude Code

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Comment on lines +26 to +32
const scrollDateFilter = useCallback((direction: 'left' | 'right') => {
const scrollAmount = (scrollRef.current?.clientWidth ?? 0) * 0.5;
scrollRef.current?.scrollBy({
left: direction === 'left' ? -scrollAmount : scrollAmount,
behavior: 'smooth',
});
}, []);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

일정 거리만큼 스크롤을 이동합니다.

PC의 <, > 버튼을 누르면 일정 거리만큼 이동하여 탐색할 수 있도록 하는 기능입니다.

Comment on lines +34 to +43
useLayoutEffect(() => {
const filterContainer = scrollRef.current;
if (!filterContainer) return;

filterContainer.scrollLeft = Math.max(
filterContainer.scrollWidth - filterContainer.clientWidth,
0,
);
updateCanScroll();
}, [dateString, updateCanScroll]);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

스크롤 위치를 초기화하는 Effect 입니다.
처음 페이지에 접속하면 가장 최근 날짜가 보이도록 하기 위해, 스크롤의 위치를 맨 우측으로 초기화 합니다.

- 유효한 챌린지 날짜(주말 제외 챌린지 기간 내 평일)만 필터로 보인다.
- 오늘이 챌린지 기간이 아니면, 마지막 챌린지 날짜가 선택된 상태이며, 라벨은 해당 날짜로 되어 있다.
- 오늘이 챌린지 기간이면 아래의 조건을 따른다.
  - 오늘이 주말이면, 가장 최근 평일 날짜의 필터가 마지막이고, 해당 날짜가 선택된 상태이다.
  - 오늘이 평일이면, 오늘 필터의 라벨이 날짜대신 '오늘'이고, 이 오늘이 선택된 상태이다.

@sanghee01 sanghee01 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🤖 PR Review

⚠️ 수정이 필요한 리뷰 코멘트가 있습니다.

날짜 필터 분리와 초기 선택 날짜 정책은 의도에 맞게 반영됐지만, 과거 날짜를 선택해도 오늘 코멘트 작성 영역이 표시되는 회귀가 있습니다.

🚨 0 Critical · ⚠️ 1 Major · 📝 0 Minor

수정 필요

  • web/src/routes/_bombom/_main/challenge/$challengeId/comments.tsx:97 — 과거 날짜 선택 시에도 오늘 코멘트 작성 영역이 노출됨 (인라인 코멘트 참조).
📋 검증 과정
  • Claude structured review 결과 중 확신도가 있는 항목만 정리했습니다.
  • Critical/Major는 inline comment로 게시하고, Minor는 참고 항목으로 summary에 포함합니다.
  • 자동 생성된 OpenAPI 타입 선언 파일과 lock 파일은 리뷰 대상에서 제외합니다.

🤖 Claude PR Review

<PCDateFilter
today={today}
dates={challengeDates}
selectedDate={activeDate}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ [Major] 과거 날짜 선택 시에도 오늘 코멘트 작성 영역이 노출됨

기존에는 selectedDate === today일 때만 작성 영역을 렌더링했지만, 이 변경 후에는 선택한 날짜와 무관하게 isChallengeDay(today)만 확인합니다. 진행 중인 챌린지에서 사용자가 이전 날짜 탭을 선택하면 해당 날짜의 코멘트를 보는 화면 위에도 오늘의 작성 버튼과 오늘 기준 후보 기사 모달이 표시됩니다. 선택 날짜의 과거 코멘트 조회 흐름과 작성 UI가 섞이지 않도록 activeDate === today 조건을 함께 확인해야 합니다.

Claude 검증: 변경 diff의 web/src/routes/_bombom/_main/challenge/$challengeId/comments.tsx:97 기준으로 확인했습니다. 실제 코드와 다르면 이 코멘트는 무시해 주세요. (confidence 0.93).

수정 제안:
이 finding이 여전히 유효한지 먼저 확인한 뒤, 관련 코드만 최소 범위로 수정하고 필요한 검증을 실행해 주세요.

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.

3 participants