Conversation
Walkthrough로컬 React DateRangePicker 컴포넌트와 관련 의존성( Changes
Sequence Diagram(s)sequenceDiagram
participant User as 사용자
participant Input as TextField
participant Pop as Popover
participant Day as DayPicker
participant Parent as EventInformation
Note over Input,Day: 색상 `#DDEBF7` 배경 (변경/새로 추가된 흐름)
사용자->>Input: 클릭 (날짜 필드)
Input->>Pop: open(anchorEl)
Pop->>Day: 렌더(범위 모드, locale=ko)
사용자->>Day: 범위 선택 (from, to)
Day-->>Input: 선택값 업데이트
Input->>Parent: onChange({from, to})
Parent->>Parent: startOfDay(from), endOfDay(to)
Day->>Pop: 완전 범위 선택 시 close
Pop->>Input: close()
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
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.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
package.json (1)
20-21: 사용하지 않는 의존성 정리 필요
@mui/x-date-pickers-pro는 코드베이스에서 전혀 사용되지 않고 있습니다. 커스텀 DateRangePicker가 react-day-picker를 기반으로 구현되어 있어 이 의존성을 제거할 수 있습니다.또한
dayjs와date-fns가 혼재되어 있습니다. dayjs는 EventInformation.tsx와 RecruitmentRound 관련 모달에서 주로 날짜 관리에 사용되고, date-fns는 DateRangePicker.tsx에서 한국어 로케일 포맷팅에만 사용되고 있습니다. dayjs의 포맷팅 기능으로 통일하는 것을 검토하세요.
🧹 Nitpick comments (4)
src/components/EditEvent/DateRangePicker.tsx (3)
9-67: 디자인 토큰 사용을 고려하세요.StyledDayPicker의 색상 값이 하드코딩되어 있습니다.
wowds-tokens의color토큰을 사용하면 일관된 디자인 시스템을 유지할 수 있습니다.또한 Lines 49-51에서
!important를 사용하고 있는데, 이는 스타일 우선순위 문제를 나타낼 수 있습니다. react-day-picker의 기본 스타일 오버라이드 방법을 확인해보세요.
98-110: 클릭 가능한 필드임을 시각적으로 표시하세요.읽기 전용 TextField가 클릭 가능하지만, 사용자에게 이를 명확히 알려주는 시각적 단서(커서 모양, 아이콘 등)가 없습니다.
🔎 제안하는 개선 사항
<TextField ref={inputRef} value={formatDateRange()} onClick={handleClick} label={"행사 신청 기간"} InputProps={{ readOnly: true, + endAdornment: ( + <InputAdornment position="end"> + <CalendarTodayIcon /> + </InputAdornment> + ), }} - style={{ backgroundColor: "white" }} + style={{ backgroundColor: "white", cursor: "pointer" }} variant="outlined" fullWidth size="small" />추가로 import가 필요합니다:
import { InputAdornment } from "@mui/material"; import CalendarTodayIcon from "@mui/icons-material/CalendarToday";
98-110: 접근성 개선을 위한 ARIA 속성을 추가하세요.스크린 리더 사용자를 위해 TextField에 적절한 ARIA 속성을 추가하면 접근성이 향상됩니다.
🔎 제안하는 개선 사항
<TextField ref={inputRef} value={formatDateRange()} onClick={handleClick} label={"행사 신청 기간"} InputProps={{ readOnly: true, + 'aria-label': '행사 신청 기간 선택', + 'aria-haspopup': 'dialog', + 'aria-expanded': open, }} style={{ backgroundColor: "white" }} variant="outlined" fullWidth size="small" />src/components/EditEvent/EventInformation.tsx (1)
1-24: 날짜 라이브러리 통합을 고려하세요.현재
dayjs와date-fns두 가지 날짜 라이브러리를 함께 사용하고 있습니다. 이는 번들 크기를 증가시키고 코드 일관성을 해칠 수 있습니다.MUI의 DatePicker와 TimePicker가 여전히 dayjs를 사용하고 있으므로, 향후 모든 날짜 처리를 단일 라이브러리로 통합하는 것을 고려해보세요.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (3)
package.jsonsrc/components/EditEvent/DateRangePicker.tsxsrc/components/EditEvent/EventInformation.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
src/components/EditEvent/EventInformation.tsx (1)
src/components/EditEvent/DateRangePicker.tsx (1)
DateRangePicker(74-129)
🔇 Additional comments (2)
src/components/EditEvent/EventInformation.tsx (1)
595-595: 좋은 방어적 코딩입니다!
description ?? ""를 사용하여 undefined 값을 방지한 것은 제어 컴포넌트의 좋은 사례입니다.package.json (1)
25-25: 패키지 버전 및 보안 상태 확인됨 —date-fns@4.1.0과react-day-picker@9.12.0은 모두 npm 레지스트리에 존재하는 유효한 버전이며, 알려진 보안 취약점이 없습니다.
date-fns@4.1.0: 현재 최신 버전, 보안 취약점 없음react-day-picker@9.12.0: 최신 버전 9.13.0 사용 가능하지만, 현재 버전도 안전함
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/components/EditEvent/DateRangePicker.tsx (1)
47-52:!important사용을 최소화하는 것을 권장합니다.CSS 우선순위를 강제하기 위해
!important를 사용하고 있습니다. 라이브러리 기본 스타일을 덮어쓰기 위해 필요할 수 있지만, 더 구체적인 선택자나 스타일 우선순위를 활용하는 방식이 유지보수에 더 유리합니다.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/components/EditEvent/DateRangePicker.tsxsrc/components/EditEvent/EventInformation.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- src/components/EditEvent/EventInformation.tsx
🔇 Additional comments (6)
src/components/EditEvent/DateRangePicker.tsx (6)
69-72: 타입 정의가 명확합니다.인터페이스가
react-day-picker의 range 모드 API와 잘 맞춰져 있으며, 선택적 속성과 콜백 시그니처가 적절하게 정의되어 있습니다.
74-86: Popover 상태 관리가 올바릅니다.MUI Popover의 표준 패턴을 정확하게 따르고 있으며, anchor element 관리와 open/close 핸들러가 적절하게 구현되어 있습니다.
88-94: 날짜 형식화 로직이 정확합니다.모든 케이스(선택 없음, 시작일만, 범위)를 올바르게 처리하고 있으며, 한국어 로케일을 일관되게 사용하고 있습니다.
96-110: TextField 구성이 적절합니다.읽기 전용 입력 필드로 설정되어 있어 사용자가 picker를 통해서만 날짜를 선택할 수 있도록 강제하고 있으며, 스타일과 속성이 적절하게 설정되어 있습니다.
140-142: 이전 리뷰 피드백이 반영되었습니다.날짜 범위가 완전히 선택되면 Popover가 자동으로 닫히도록 구현되어 있습니다. 사용성이 개선되었습니다.
1-7: 외부 라이브러리 버전 및 호환성 검증 완료
date-fns4.1.0과react-day-picker9.12.0은 모두 최신 버전이며 호환성이 검증되었습니다. date-fns 4.1.0은 알려진 보안 취약점이 없고, react-day-picker 9.12.0은 date-fns ^4.x에 대한 의존성을 가지고 있어 현재 프로젝트의 버전 구성이 최적으로 구성되어 있습니다.
| onSelect={range => { | ||
| // 기간이 선택되어있을 때 새로운 날짜 클릭 시 시작일부터 다시 선택하도록 | ||
| if (value?.from && value?.to && range?.from) { | ||
| const clickedDate = | ||
| range.from.getTime() !== value.from.getTime() ? range.from : range.to; | ||
|
|
||
| onChange({ from: clickedDate, to: undefined }); | ||
| return; | ||
| } | ||
|
|
||
| onChange(range); | ||
|
|
||
| if (range?.from && range?.to) { | ||
| handleClose(); | ||
| } | ||
| }} |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -name "DateRangePicker.tsx" -type fRepository: gdg-hongik-univ/gdsc-admin
Length of output: 116
🏁 Script executed:
cat -n ./src/components/EditEvent/DateRangePicker.tsxRepository: gdg-hongik-univ/gdsc-admin
Length of output: 4779
🏁 Script executed:
cd . && find . -name "package.json" -type f | head -5 | xargs grep -l "react-day-picker"Repository: gdg-hongik-univ/gdsc-admin
Length of output: 84
🏁 Script executed:
cat ./package.json | grep -A 2 -B 2 "react-day-picker"Repository: gdg-hongik-univ/gdsc-admin
Length of output: 221
🌐 Web query:
react-day-picker v9 range mode onSelect behavior when clicking date after range selected
💡 Result:
Short answer: in v9 DayPicker's range mode keeps internal state, so after a completed range is selected a subsequent click typically adjusts the existing range (moves start or end) instead of automatically clearing it — you can still implement "reset on click" in onSelect when controlled, but you'll see a small flicker because the internal state updates first then the controlled prop overrides it. [1][2][3]
What to do
- Docs: range mode is intended to be controlled via selected + onSelect. [2]
- Behavior & bug: the internal-state + controlled-state interaction (and the resulting flicker) is described in issue #2362. [1]
- Workarounds:
- Implement reset in onSelect: if selected.from && selected.to then set selected = { from: clickedDate, to: undefined }. This works functionally but may flicker. [1][2]
- To avoid visual flicker, force a remount when you reset (e.g. change a key on the DayPicker) so the component's internal state is cleared immediately. (Common React workaround; used for similar date-picker issues). [4]
- Related notes: v9 changed some range semantics vs v8 (e.g. clicking the same day twice behavior). See related issue. [3]
Sources
- Range internal-state / controlled interaction (issue #2362). [1]
- Range mode docs (props: selected, onSelect, min/max, required). [2]
- Change in v9 range click semantics (issue #2302). [3]
- Remount/key workaround pattern (StackOverflow example). [4]
range.to가 undefined일 수 있어 런타임 오류 발생 가능합니다.
Line 130의 조건 (value?.from && value?.to && range?.from)을 통과하더라도, react-day-picker v9의 범위 모드에서 사용자가 완료된 범위 이후 새로운 날짜를 클릭하면 range는 { from: clickedDate, to: undefined }를 전달합니다.
이 경우 Line 132의 삼항 연산자는 range.to를 평가하게 되어 clickedDate가 undefined가 되고, Line 134에서 onChange({ from: undefined, to: undefined })를 호출하게 됩니다.
Line 132를 다음과 같이 수정하여 안전성을 확보하세요:
- const clickedDate =
- range.from.getTime() !== value.from.getTime() ? range.from : range.to;
+ const clickedDate =
+ range.from.getTime() !== value.from.getTime() ? range.from : (range.to || range.from);또는 더 간단하게, 완료된 범위 상태에서 새 클릭 시 항상 새 범위의 from을 시작점으로 설정하는 방식으로 전체 조건을 제거할 수도 있습니다.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| onSelect={range => { | |
| // 기간이 선택되어있을 때 새로운 날짜 클릭 시 시작일부터 다시 선택하도록 | |
| if (value?.from && value?.to && range?.from) { | |
| const clickedDate = | |
| range.from.getTime() !== value.from.getTime() ? range.from : range.to; | |
| onChange({ from: clickedDate, to: undefined }); | |
| return; | |
| } | |
| onChange(range); | |
| if (range?.from && range?.to) { | |
| handleClose(); | |
| } | |
| }} | |
| onSelect={range => { | |
| // 기간이 선택되어있을 때 새로운 날짜 클릭 시 시작일부터 다시 선택하도록 | |
| if (value?.from && value?.to && range?.from) { | |
| const clickedDate = | |
| range.from.getTime() !== value.from.getTime() ? range.from : (range.to || range.from); | |
| onChange({ from: clickedDate, to: undefined }); | |
| return; | |
| } | |
| onChange(range); | |
| if (range?.from && range?.to) { | |
| handleClose(); | |
| } | |
| }} |
🤖 Prompt for AI Agents
In src/components/EditEvent/DateRangePicker.tsx around lines 128-143, the
current onSelect handler can read range.to when it may be undefined; change the
logic so clickedDate is never undefined — either (A) replace the ternary with a
safe expression that falls back when range.to is missing (e.g. prefer range.from
and only use range.to if present), or (B) simplify by always using range.from as
the new start when a completed range is clicked (remove the complex condition
and set onChange({ from: range.from, to: undefined }) ), and ensure you only
access range.from/to after checking range is defined.
Describe your changes
QA 내용

To Reviewers
Summary by CodeRabbit
New Features
Bug Fixes
Chores
✏️ Tip: You can customize this high-level summary in your review settings.