-
Notifications
You must be signed in to change notification settings - Fork 2
[SRLT-127] 랜딩페이지 프로모션 실시간 타이머 설정 구현 #94
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: "SRLT-127-\uB79C\uB529\uD398\uC774\uC9C0-\uC2DC\uAC04\uD0C0\uC774\uBA38-\uC124\uC815"
Conversation
Walkthrough새로운 Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Browser as Browser (LandingChecklist)
participant Hook as useCountdown Hook
participant Timer as setInterval (환경 타이머)
participant Render as React Renderer
Note over Browser,Hook: 컴포넌트 마운트 시
Browser->>Hook: useCountdown(targetDate)
Hook->>Hook: calculateTimeLeft(targetDate) (초기 계산)
Hook-->>Browser: 초기 timeLeft 반환 (state)
Hook->>Timer: setInterval(1s) 시작
Timer->>Hook: tick -> calculateTimeLeft(targetDate)
Hook-->>Browser: 업데이트된 timeLeft (state 변경)
Browser->>Render: re-render countdown UI (days/hours/minutes/seconds)
Note over Hook,Timer: 목표일 경과 시 timeLeft = 0으로 고정 및 타이머 정리
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
시
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (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: 4
🤖 Fix all issues with AI agents
In @src/app/_components/landing/LandingChecklist.tsx:
- Around line 5-9: LandingChecklist is directly calling useCountdown during SSR
which causes hydration mismatch and non-deterministic timezone behavior; fix by
moving countdown logic to a client-only component (e.g., create CountdownTimer
that uses useCountdown('2026-02-28T23:59:59+09:00')) and dynamically import it
in LandingChecklist (use Next.js dynamic import or React.lazy with suspense) so
useCountdown runs only on the client, and ensure the deadline string includes
the explicit timezone (+09:00) to guarantee consistent end time across locales.
- Line 9: The countdown target is parsed as UTC because the string
'2026-02-28T23:59:59' has no timezone; update the call in LandingChecklist (the
useCountdown invocation) to use an explicit KST offset like
'2026-02-28T23:59:59+09:00' or alternatively update the useCountdown hook to
accept a timezone param or treat naive ISO strings as KST (convert/adjust the
parsed Date by +9 hours) so the countdown ends at the intended KST moment.
In @src/hooks/useCountdown.ts:
- Around line 3-9: The hook currently initializes timeLeft to zeros which causes
SSR hydration mismatch when the client immediately recalculates in useEffect;
change useCountdown so the initial useState uses a lazy initializer that
synchronously computes the remaining time from the provided targetDate (e.g.,
via a helper like calculateTimeLeft or getTimeLeft that parses targetDate and
returns {days,hours,minutes,seconds}) and reuse that same helper inside the
interval callback and cleanup logic; ensure you reference useCountdown,
setTimeLeft, and the new calculateTimeLeft/getTimeLeft helper so the first
render already reflects the computed countdown instead of all zeros.
- Line 12: The code uses new Date(targetDate).getTime() which parses
timezone-less strings in the local timezone causing inconsistent countdowns;
update useCountdown (the target constant) to parse or normalize the input to an
explicit timezone/UTC: either require callers to pass an ISO string with offset
(e.g., '2026-02-28T23:59:59+09:00') or convert the received targetDate to a UTC
timestamp using a timezone-aware parser (e.g., parse as UTC or append '+00:00'
or '+09:00' as appropriate) before calling getTime(), and validate/throw if the
string is ambiguous so target in useCountdown is always deterministic.
🧹 Nitpick comments (1)
src/app/_components/landing/LandingChecklist.tsx (1)
26-40: 동적 카운트다운 구현 확인카운트다운 로직이 올바르게 동작하지만, 몇 가지 개선 사항이 있습니다:
- Key prop: Line 33에서
key={index}사용은 권장되지 않습니다. 배열 순서가 안정적이긴 하지만, 더 명확한 key를 사용하는 것이 좋습니다.♻️ 개선 제안
{[ { value: timeLeft.days, label: '일' }, { value: timeLeft.hours, label: '시간' }, { value: timeLeft.minutes, label: '분' }, { value: timeLeft.seconds, label: '초' }, ].map((item, index) => ( <div - key={index} + key={item.label} className="ds-heading flex h-[86px] w-[120px] items-center justify-center rounded-lg bg-gray-900 py-10 font-semibold text-white" >또는 배열을 컴포넌트 외부로 분리하여 재생성 방지:
+const TIME_UNITS = [ + { key: 'days', label: '일' }, + { key: 'hours', label: '시간' }, + { key: 'minutes', label: '분' }, + { key: 'seconds', label: '초' }, +] as const; + const LandingChecklist = () => { const router = useRouter(); const timeLeft = useCountdown('2026-02-28T23:59:59+09:00'); return ( // ... - {[ - { value: timeLeft.days, label: '일' }, - { value: timeLeft.hours, label: '시간' }, - { value: timeLeft.minutes, label: '분' }, - { value: timeLeft.seconds, label: '초' }, - ].map((item, index) => ( + {TIME_UNITS.map((unit) => ( <div - key={index} + key={unit.key} className="ds-heading flex h-[86px] w-[120px] items-center justify-center rounded-lg bg-gray-900 py-10 font-semibold text-white" > - {item.value} - {item.label} + {timeLeft[unit.key]} + {unit.label} </div> ))}
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/app/_components/landing/LandingChecklist.tsxsrc/hooks/useCountdown.ts
🧰 Additional context used
🧬 Code graph analysis (1)
src/app/_components/landing/LandingChecklist.tsx (1)
src/hooks/useCountdown.ts (1)
useCountdown(3-37)
🔇 Additional comments (1)
src/hooks/useCountdown.ts (1)
30-34: 정리 로직이 올바르게 구현되었습니다
clearInterval을 사용한 cleanup 함수가 정확하며, targetDate가 변경될 때 이전 interval이 올바르게 정리됩니다. 메모리 누수 우려가 없습니다.
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
🤖 Fix all issues with AI agents
In @src/hooks/useCountdown.ts:
- Around line 30-43: The updateTimer function duplicates the time-difference
logic already implemented in calculateTimeLeft; replace the inlined computation
inside updateTimer with a single call to calculateTimeLeft (passing the same
target value or eliminating the redundant local target if calculateTimeLeft
closes over it) and call setTimeLeft with the result, removing the duplicated
block so all time calculation lives in calculateTimeLeft and updateTimer only
invokes it and updates state.
parknari02
left a 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.
확인했씁니다 !! 수고하셨습니당
#️⃣ 관련 이슈
✍️ 작업 내용 요약
💡 작업 내용
기능
🖥️ 구현 화면
기타 사항
x
Summary by CodeRabbit
새로운 기능
스타일 / 레이아웃
✏️ Tip: You can customize this high-level summary in your review settings.