Feat(client): remind card remaining timer 기능 추가#160
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughRemindCard 컴포넌트에 로컬 타이머 표시 로직이 추가되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant U as User
participant RC as RemindCard
participant T as Timer (setInterval)
U->>RC: 컴포넌트 마운트 (timeRemaining 전달)
RC->>RC: endTime 계산 (timeRemaining + 24h)
RC->>T: setInterval(매 분)
T-->>RC: 현재 시간 기준 남은시간 계산
alt 남은시간 > 0
RC->>RC: displayTime = "H시간 M분"
else 만료
RC->>RC: displayTime = "시간 만료"
end
RC-->>U: displayTime 렌더링
U->>RC: 언마운트/prop 변경
RC->>T: clearInterval
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests
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 |
|
✅ Storybook chromatic 배포 확인: |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/design-system/src/components/card/RemindCard.tsx(2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#2
File: pnpm-workspace.yaml:3-3
Timestamp: 2025-08-18T13:48:59.065Z
Learning: constantly-dev는 docs 디렉터리를 컨벤션 문서 추가용으로 사용할 예정이라고 명시했습니다.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: storybook
| const endTime = new Date(timeRemaining).getTime() + 24 * 60 * 60 * 1000; | ||
|
|
||
| const updateRemainingTime = () => { | ||
| const now = new Date().getTime(); | ||
| const remainingMilliseconds = endTime - now; | ||
|
|
||
| if (remainingMilliseconds <= 0) { | ||
| setDisplayTime('시간 만료'); | ||
| } else { | ||
| const totalMinutes = Math.floor(remainingMilliseconds / (1000 * 60)); | ||
| const hours = Math.floor(totalMinutes / 60); | ||
| const minutes = totalMinutes % 60; | ||
| setDisplayTime(`${hours}시간 ${minutes}분`); | ||
| } | ||
| }; | ||
|
|
||
| const intervalId = setInterval(updateRemainingTime, 60000); | ||
|
|
||
| updateRemainingTime(); | ||
|
|
||
| return () => { | ||
| clearInterval(intervalId); | ||
| }; |
There was a problem hiding this comment.
날짜 파싱 실패 시 남은 시간이 NaN시간 NaN분으로 깨집니다.
이번 변경은 timeRemaining을 ISO 날짜 문자열이라고 가정하고 new Date(timeRemaining)로 파싱한 뒤 24시간을 더하고 있습니다. 하지만 이 필드가 빈 문자열이거나 기존처럼 "3시간 20분" 같은 표현식 문자열로 넘어오면 Date.parse 결과가 NaN이 되어 UI에 NaN시간 NaN분이 노출됩니다. 실제 백엔드 응답 포맷이 날짜가 아닐 경우 프로덕션에서 바로 재현되는 치명적인 기능 오류입니다. 최소한 파싱 실패 시 기존 문자열을 그대로 보여주는 방어 로직이 필요합니다. 아래와 같이 가드를 추가해 주세요.
- const endTime = new Date(timeRemaining).getTime() + 24 * 60 * 60 * 1000;
+ const parsed = Date.parse(timeRemaining);
+ if (Number.isNaN(parsed)) {
+ setDisplayTime(timeRemaining ?? '');
+ return;
+ }
+
+ const endTime = parsed + 24 * 60 * 60 * 1000;📝 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.
| const endTime = new Date(timeRemaining).getTime() + 24 * 60 * 60 * 1000; | |
| const updateRemainingTime = () => { | |
| const now = new Date().getTime(); | |
| const remainingMilliseconds = endTime - now; | |
| if (remainingMilliseconds <= 0) { | |
| setDisplayTime('시간 만료'); | |
| } else { | |
| const totalMinutes = Math.floor(remainingMilliseconds / (1000 * 60)); | |
| const hours = Math.floor(totalMinutes / 60); | |
| const minutes = totalMinutes % 60; | |
| setDisplayTime(`${hours}시간 ${minutes}분`); | |
| } | |
| }; | |
| const intervalId = setInterval(updateRemainingTime, 60000); | |
| updateRemainingTime(); | |
| return () => { | |
| clearInterval(intervalId); | |
| }; | |
| const parsed = Date.parse(timeRemaining); | |
| if (Number.isNaN(parsed)) { | |
| setDisplayTime(timeRemaining ?? ''); | |
| return; | |
| } | |
| const endTime = parsed + 24 * 60 * 60 * 1000; | |
| const updateRemainingTime = () => { | |
| const now = new Date().getTime(); | |
| const remainingMilliseconds = endTime - now; | |
| if (remainingMilliseconds <= 0) { | |
| setDisplayTime('시간 만료'); | |
| } else { | |
| const totalMinutes = Math.floor(remainingMilliseconds / (1000 * 60)); | |
| const hours = Math.floor(totalMinutes / 60); | |
| const minutes = totalMinutes % 60; | |
| setDisplayTime(`${hours}시간 ${minutes}분`); | |
| } | |
| }; | |
| const intervalId = setInterval(updateRemainingTime, 60000); | |
| updateRemainingTime(); | |
| return () => { | |
| clearInterval(intervalId); | |
| }; |
📌 Related Issues
📄 Tasks
⭐ PR Point (To Reviewer)
📷 Screenshot
Summary by CodeRabbit