feat: 인증/온보딩 페이지 ui 제작#29
Conversation
dev to main
|
Warning Review limit reached
Next review available in: 45 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
Walkthrough로그인·정책·온보딩·추천 플로우와 관련 라우팅 및 레이아웃을 추가했습니다. 공통 UI 컴포넌트와 피드백 export 경로를 정리하고, 카드·단계·페이지 진입 애니메이션 및 reduced-motion 스타일을 확장했습니다. Changes공통 UI 및 피드백 컴포넌트
인증·정책 화면과 랜딩 이동
레이아웃과 라우팅
온보딩 단계 흐름
추천 플로우
전역 스타일
커밋 규칙과 리뷰 지침
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
🚦 CI 검증 결과
|
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/components/layout/Header.tsx (1)
118-135: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win좁은 화면에서 탭 헤더가 가로로 넘칩니다.
w-251 shrink-0만 1004px이고 로고·프로필도 축소되지 않아, 1024px 뷰포트에서는 헤더가 오버플로됩니다. 내비게이션을flex-1 min-w-0 max-w-251로 제한하고 작은 화면의 패딩·탭 오버플로 전략을 추가하세요.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/layout/Header.tsx` around lines 118 - 135, Update the HeaderTabNav layout in the HeaderTabShell to use flex-1 min-w-0 with max-w-251 instead of fixed w-251 shrink-0, and add responsive reductions for horizontal padding on narrow screens. Ensure the tab navigation handles overflow within its available width while keeping the logo and profile elements visible without horizontal overflow.
🧹 Nitpick comments (1)
src/styles/global.css (1)
1-164: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
@layer없이 선언된 커스텀 클래스, Tailwind v4에서 유틸리티 오버라이드 무력화 가능.이 파일의
@keyframes와.landing-reveal*/.onboarding-step-enter*/.recommendation-pending-enter클래스가@layer로 감싸이지 않은 최상위(unlayered) 컨텍스트에 있습니다. Tailwind v4는 네이티브 cascade layers를 사용하므로, unlayered 규칙은 특이성/소스 순서와 무관하게 layered 유틸리티(@layer utilities)를 항상 이깁니다. 지금은 직접 충돌하는 유틸리티 조합이 보이지 않지만, 향후cn()으로 같은 속성(opacity,transform등)을 오버라이드하려는 Tailwind 유틸리티 클래스를 붙이면 조용히 무시될 수 있습니다.♻️ 제안 리팩터
+@layer components { `@keyframes` landing-fade-slide-up { ... } ... .landing-reveal { opacity: 0; } ... +}프로젝트의 레이어 순서 설정(
@layer theme, base, components, utilities;등)을 확인해 실제로 유틸리티 오버라이드가 필요한 상황에서 문제가 없는지 검증을 권장합니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/styles/global.css` around lines 1 - 164, Wrap the landing, onboarding, and recommendation animation definitions in the project’s appropriate named cascade layer, preferably the configured components layer, including their `@keyframes` and related class rules. Reuse the project’s existing `@layer` order declaration if present so Tailwind utility classes can override properties such as opacity and transform when applied through cn().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/common/Tag.tsx`:
- Around line 7-30: Update the button rendered by Tag so the select variant
exposes its selection state via aria-pressed={selected}. Preserve the existing
selected styling and avoid applying this attribute to non-select variants unless
required by the component’s API.
In `@src/features/jobs/components/RecommendationPendingContent.tsx`:
- Around line 42-48: Update the action buttons in RecommendationPendingContent
so “공고 둘러보기” and “프로필 보완” either navigate to their intended destination routes
with click handlers or are rendered disabled until those routes are available;
ensure neither button remains interactive without behavior.
In `@src/features/onboarding/components/OnboardingConfirmStep.tsx`:
- Around line 40-45: Update the 수정 button in OnboardingConfirmStep so it has an
onClick handler that invokes the appropriate item-specific edit callback and
transitions to that onboarding step; if those callbacks or navigation are not
supported, hide the 수정 button instead of rendering a no-op control.
In `@src/features/onboarding/components/OnboardingQuizStep.tsx`:
- Around line 5-12: OnboardingQuizStep의 QUESTIONS와 TOTAL_QUESTIONS 간 불일치를 수정하세요.
실제 문항 배열을 10개로 완성하거나, TOTAL_QUESTIONS 및 진행률·마지막 문항 판정 로직(선택 처리와 확인 단계 이동)을
QUESTIONS.length에서 파생해 현재 문항 수와 일치시키세요.
In `@src/pages/PolicyPage/PolicyPage.tsx`:
- Around line 20-25: Update the initial state in PolicyPage’s checked useState
so all required consent entries—terms, privacy, and age—start as false, while
preserving marketing’s existing false default; users must explicitly select each
required item before consent is recorded.
- Line 53: PolicyPage의 “다음” Button에 클릭 동작을 연결해 필수 약관 항목이 모두 선택된 경우에만 다음 온보딩 단계
또는 기존 의도 경로로 이동하도록 구현하세요. 선택이 완료되지 않은 상태에서는 진행되지 않도록 검증을 유지하고, 관련 상태와 라우팅 흐름을
재사용하세요.
In `@src/routes/router.tsx`:
- Around line 26-31: Align the policy links with the registered routes: in
src/routes/router.tsx lines 26-31, register /terms and /privacy using the
appropriate policy page components, and in src/pages/LoginPage/LoginPage.tsx
lines 30-42, update the terms and privacy links to those registered paths.
Ensure both links navigate to existing routes instead of NotFoundPage.
---
Outside diff comments:
In `@src/components/layout/Header.tsx`:
- Around line 118-135: Update the HeaderTabNav layout in the HeaderTabShell to
use flex-1 min-w-0 with max-w-251 instead of fixed w-251 shrink-0, and add
responsive reductions for horizontal padding on narrow screens. Ensure the tab
navigation handles overflow within its available width while keeping the logo
and profile elements visible without horizontal overflow.
---
Nitpick comments:
In `@src/styles/global.css`:
- Around line 1-164: Wrap the landing, onboarding, and recommendation animation
definitions in the project’s appropriate named cascade layer, preferably the
configured components layer, including their `@keyframes` and related class rules.
Reuse the project’s existing `@layer` order declaration if present so Tailwind
utility classes can override properties such as opacity and transform when
applied through cn().
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 50c41507-554b-4525-be75-694437545a53
⛔ Files ignored due to path filters (9)
src/assets/icons/icon-carousel-arrow-large-left.svgis excluded by!**/*.svgsrc/assets/icons/icon-carousel-arrow-large-right.svgis excluded by!**/*.svgsrc/assets/icons/icon-carousel-arrow-medium-left.svgis excluded by!**/*.svgsrc/assets/icons/icon-carousel-arrow-medium-right.svgis excluded by!**/*.svgsrc/assets/icons/icon-carousel-arrow-small-left.svgis excluded by!**/*.svgsrc/assets/icons/icon-carousel-arrow-small-right.svgis excluded by!**/*.svgsrc/assets/icons/icon-google.svgis excluded by!**/*.svgsrc/assets/icons/icon-kakao.svgis excluded by!**/*.svgsrc/assets/images/avatar-default-profile.pngis excluded by!**/*.png
📒 Files selected for processing (38)
.coderabbit.yamlcommitlint.config.jsdocs/GIT_WORKFLOW.mdsrc/components/common/Button.tsxsrc/components/common/CarouselArrow.tsxsrc/components/common/CarouselIndicator.tsxsrc/components/common/Tab.tsxsrc/components/common/Tag.tsxsrc/components/common/index.tssrc/components/feedback/Alert.tsxsrc/components/feedback/ProgressStepper.tsxsrc/components/feedback/ResultIcon.tsxsrc/components/feedback/Spinner.tsxsrc/components/feedback/index.tssrc/components/layout/Header.tsxsrc/components/layout/MainLayout.tsxsrc/features/auth/.gitkeepsrc/features/jobs/components/JobCard.tsxsrc/features/jobs/components/RecommendationPendingContent.tsxsrc/features/landing/components/LandingContent.tsxsrc/features/landing/components/LandingHero.tsxsrc/features/login/components/SocialLoginButton.tsxsrc/features/login/hooks/.gitkeepsrc/features/onboarding/components/OnboardingConfirmStep.tsxsrc/features/onboarding/components/OnboardingProfileStep.tsxsrc/features/onboarding/components/OnboardingQuizStep.tsxsrc/features/onboarding/hooks/.gitkeepsrc/pages/CallbackPage/CallbackPage.tsxsrc/pages/LandingPage/LandingPage.tsxsrc/pages/LoginFailPage/LoginFailPage.tsxsrc/pages/LoginPage/LoginPage.tsxsrc/pages/OnboardingPage/OnboardingPage.tsxsrc/pages/PlaygroundPage/PlaygroundPage.tsxsrc/pages/PolicyPage/PolicyPage.tsxsrc/pages/RecommendationsPage/RecommendationsPage.tsxsrc/routes/router.tsxsrc/styles/global.csssrc/styles/index.css
💤 Files with no reviewable changes (1)
- src/components/common/index.ts
| <div className="flex items-center justify-center gap-2.5"> | ||
| <Button variant="outline" className="w-37.5"> | ||
| 공고 둘러보기 | ||
| </Button> | ||
| <Button variant="outline" className="w-37.5"> | ||
| 프로필 보완 | ||
| </Button> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
대기 화면의 행동 버튼이 동작하지 않습니다.
공고 둘러보기와 프로필 보완은 클릭 핸들러나 이동 대상이 없어 아무 작업도 수행하지 않습니다. 목적지 라우트에 연결하거나, 제공 전까지 비활성 상태로 표시하세요.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/features/jobs/components/RecommendationPendingContent.tsx` around lines
42 - 48, Update the action buttons in RecommendationPendingContent so “공고 둘러보기”
and “프로필 보완” either navigate to their intended destination routes with click
handlers or are rendered disabled until those routes are available; ensure
neither button remains interactive without behavior.
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
src/features/onboarding/components/OnboardingConfirmStep.tsx (1)
42-45: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift모든
수정이 프로필 단계로만 이동합니다.이력서·선호 조건 등은 프로필 단계에서 수정할 수 없는데도 동일한 콜백으로 처리됩니다. 항목별 편집 대상을 전달해 해당 단계로 이동시키거나, 현재 수정 가능한 항목에만
수정을 노출하세요.
src/features/onboarding/components/OnboardingConfirmStep.tsx#L42-L45: 요약 항목별 편집 대상 또는 콜백을 전달하세요.src/pages/OnboardingPage/OnboardingPage.tsx#L95-L95: 전달받은 대상에 따라 해당 편집 단계로 전환하세요.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/features/onboarding/components/OnboardingConfirmStep.tsx` around lines 42 - 45, Update OnboardingConfirmStep.tsx at lines 42-45 to associate each summary item’s 수정 action with its intended onboarding step or callback instead of routing every item through onEdit; update OnboardingPage.tsx at line 95 to consume that target and transition to the corresponding edit step, while only showing 수정 for items that support editing.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/features/login/components/LoginDefaultContent.tsx`:
- Around line 27-39: Update the terms and privacy anchor destinations in
LoginDefaultContent to use routes registered by the application, replacing the
invalid /terms and /privacy paths with the corresponding policy screen paths or
registering those routes in the router. Ensure both links resolve without
NotFound.
In `@src/features/login/components/LoginEmailRequiredContent.tsx`:
- Around line 10-17: LoginEmailRequiredContent의 이메일 입력과 확인 메일 보내기 Button을 실제 이메일
인증 발송 흐름에 연결하세요. 입력값을 상태로 관리하고 유효성을 검증한 뒤 발송 핸들러에서 인증 메일 요청을 호출하며, 지원되는 발송 로직이
없다면 버튼을 비활성화해 동작하지 않는 CTA로 남지 않게 하세요.
---
Duplicate comments:
In `@src/features/onboarding/components/OnboardingConfirmStep.tsx`:
- Around line 42-45: Update OnboardingConfirmStep.tsx at lines 42-45 to
associate each summary item’s 수정 action with its intended onboarding step or
callback instead of routing every item through onEdit; update OnboardingPage.tsx
at line 95 to consume that target and transition to the corresponding edit step,
while only showing 수정 for items that support editing.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 1ccabda3-dfa9-4d0e-aba1-3bfabd78289d
📒 Files selected for processing (16)
src/components/common/Checkbox.tsxsrc/components/common/Tag.tsxsrc/components/layout/AuthLayout.tsxsrc/components/layout/MainLayout.tsxsrc/features/login/components/LoginCallbackContent.tsxsrc/features/login/components/LoginDefaultContent.tsxsrc/features/login/components/LoginEmailRequiredContent.tsxsrc/features/login/components/LoginFailureContent.tsxsrc/features/onboarding/components/OnboardingConfirmStep.tsxsrc/features/onboarding/components/OnboardingProfileStep.tsxsrc/pages/CallbackPage/CallbackPage.tsxsrc/pages/LoginPage/LoginPage.tsxsrc/pages/OnboardingPage/OnboardingPage.tsxsrc/pages/PolicyPage/PolicyPage.tsxsrc/routes/router.tsxsrc/styles/global.css
🚧 Files skipped from review as they are similar to previous changes (4)
- src/routes/router.tsx
- src/styles/global.css
- src/components/common/Tag.tsx
- src/features/onboarding/components/OnboardingProfileStep.tsx
| <a | ||
| href="/terms" | ||
| className="text-text-secondary underline decoration-solid decoration-from-font [text-underline-position:from-font]" | ||
| > | ||
| 이용약관 | ||
| </a>{' '} | ||
| •{' '} | ||
| <a | ||
| href="/privacy" | ||
| className="text-text-secondary underline decoration-solid decoration-from-font [text-underline-position:from-font]" | ||
| > | ||
| 개인정보처리방침 | ||
| </a> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
약관 링크를 등록된 경로로 연결하세요.
/terms와 /privacy는 제공된 라우터에 없고 /policy만 등록되어 있어 클릭 시 NotFound로 이동합니다. 각각의 정책 라우트를 등록하거나 실제 정책 화면 경로로 변경하세요.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/features/login/components/LoginDefaultContent.tsx` around lines 27 - 39,
Update the terms and privacy anchor destinations in LoginDefaultContent to use
routes registered by the application, replacing the invalid /terms and /privacy
paths with the corresponding policy screen paths or registering those routes in
the router. Ensure both links resolve without NotFound.
| <input | ||
| type="email" | ||
| aria-label="이메일 주소" | ||
| placeholder="min****@naver.com" | ||
| className="h-10 w-full rounded-sm border border-gray-700 bg-white px-4 text-label-medium font-medium text-gray-700 placeholder:text-gray-700 focus:border-primary-500 focus:outline-none" | ||
| /> | ||
| </div> | ||
| <Button className="w-full max-w-104">확인 메일 보내기</Button> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
확인 메일 발송 CTA가 동작하지 않습니다.
입력값을 읽거나 검증하는 로직과 발송 핸들러가 없어 버튼을 눌러도 아무 일도 일어나지 않습니다. 이메일 인증 흐름에 연결하거나, 지원 전까지 비활성 상태로 처리하세요.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/features/login/components/LoginEmailRequiredContent.tsx` around lines 10
- 17, LoginEmailRequiredContent의 이메일 입력과 확인 메일 보내기 Button을 실제 이메일 인증 발송 흐름에
연결하세요. 입력값을 상태로 관리하고 유효성을 검증한 뒤 발송 핸들러에서 인증 메일 요청을 호출하며, 지원되는 발송 로직이 없다면 버튼을
비활성화해 동작하지 않는 CTA로 남지 않게 하세요.
j2nnif2r
left a comment
There was a problem hiding this comment.
추가하신 부분들 확인했습니다. 수고 많으셨습니다.
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/features/jobs/components/JobDetailMatchReasons.tsx (1)
15-16: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
matchScore를 0~100 범위로 보정하세요.현재
number타입만 보장하므로 잘못된 값이적합도 150%또는 음수로 표시될 수 있습니다.ProgressStepper처럼 표시 전에 유효 범위를 보정하거나 입력 경계에서 검증해 주세요.수정 예시
+const normalizedMatchScore = Number.isFinite(matchScore) + ? Math.min(100, Math.max(0, matchScore)) + : 0; + <Badge type="solid" color="primary"> - 적합도 {matchScore}% + 적합도 {normalizedMatchScore}% </Badge>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/features/jobs/components/JobDetailMatchReasons.tsx` around lines 15 - 16, Badge의 matchScore 표시값이 0~100 범위를 벗어나지 않도록 보정하세요. JobDetailMatchReasons의 렌더링에서 표시 전에 matchScore를 최소 0, 최대 100으로 제한하고, 보정된 값을 적합도 퍼센트에 사용하세요.
♻️ Duplicate comments (1)
src/features/recommendations/components/RecommendationPendingContent.tsx (1)
42-49: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win대기 화면의 "공고 둘러보기"/"프로필 보완" 버튼이 여전히 동작하지 않습니다.
이전 리뷰에서 지적된 이슈가 이번 diff에서도 그대로 남아 있습니다. 목적지 라우트에 연결하거나 제공 전까지 비활성 상태로 표시해야 합니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/features/recommendations/components/RecommendationPendingContent.tsx` around lines 42 - 49, RecommendationPendingContent의 “공고 둘러보기”와 “프로필 보완” Button에 각각 올바른 목적지 라우트 이동 동작을 연결하거나, 라우트가 제공되기 전까지 disabled 상태로 표시하세요. 두 버튼이 클릭 가능한 상태로 남아 있으면서 아무 동작도 하지 않지 않도록 처리하세요.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/features/onboarding/components/OnboardingQuizStep.tsx`:
- Around line 53-61: Cancel any pending selection timer and clear
pendingSelection when the previous or skip handlers run in OnboardingQuizStep,
preventing the delayed onSelect from applying after navigation; alternatively,
disable both controls while selectionTimerRef is pending. Ensure the existing
handleSelect flow remains unchanged for normal selections.
In `@src/features/recommendations/components/RecommendationFlowContent.tsx`:
- Around line 220-263: RecommendationNoticePanel의 primary Button에서 empty-signup과
empty-before-send 상태가 무반응이 되지 않도록 처리하세요. 각 화면에 실제 동작을 연결할 수 있으면 empty-signup은
온보딩 프로필 이동, empty-before-send는 새로고침 트리거를 연결하고, 목적지가 없으면 해당 상태에서 Button을 disabled
처리하세요. empty-candidates의 기존 탐색 이동 동작은 유지하세요.
In `@src/features/recommendations/components/RecommendationGreeting.tsx`:
- Around line 41-50: Update the decorative SunIcon in RecommendationGreeting to
include aria-hidden="true", matching the existing accessibility pattern used by
MailIcon and ResultIcon.
In `@src/features/recommendations/components/RecommendationLetterCarousel.tsx`:
- Around line 42-79: Move the isAnimating update into the contentKey-change
transition effect so every transition, including those triggered by onSave or
onDismiss, sets it before the animation begins and clears it after the existing
440ms timeout. Remove the arrow-only isAnimating assignments from handlePrev and
handleNext while preserving their guards and navigation behavior.
- Around line 92-104: Update the leavingContent wrapper in
RecommendationLetterCarousel so the outgoing card subtree is marked aria-hidden
during its transition. Keep the existing animation and pointer-events behavior
unchanged, ensuring focusable controls in the leaving card cannot receive
keyboard focus while it is being removed.
---
Outside diff comments:
In `@src/features/jobs/components/JobDetailMatchReasons.tsx`:
- Around line 15-16: Badge의 matchScore 표시값이 0~100 범위를 벗어나지 않도록 보정하세요.
JobDetailMatchReasons의 렌더링에서 표시 전에 matchScore를 최소 0, 최대 100으로 제한하고, 보정된 값을 적합도
퍼센트에 사용하세요.
---
Duplicate comments:
In `@src/features/recommendations/components/RecommendationPendingContent.tsx`:
- Around line 42-49: RecommendationPendingContent의 “공고 둘러보기”와 “프로필 보완” Button에
각각 올바른 목적지 라우트 이동 동작을 연결하거나, 라우트가 제공되기 전까지 disabled 상태로 표시하세요. 두 버튼이 클릭 가능한 상태로
남아 있으면서 아무 동작도 하지 않지 않도록 처리하세요.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 29948173-37df-4866-a394-ce7778838ddd
⛔ Files ignored due to path filters (1)
src/assets/icons/logo.svgis excluded by!**/*.svg
📒 Files selected for processing (23)
src/components/common/Button.tsxsrc/components/common/CarouselArrow.tsxsrc/components/common/Tag.tsxsrc/components/feedback/ResultIcon.tsxsrc/components/layout/AuthLayout.tsxsrc/components/layout/Header.tsxsrc/components/layout/MainLayout.tsxsrc/features/jobs/components/JobDetailMatchReasons.tsxsrc/features/onboarding/components/OnboardingProfileStep.tsxsrc/features/onboarding/components/OnboardingQuizStep.tsxsrc/features/recommendations/components/RecommendationFlowContent.tsxsrc/features/recommendations/components/RecommendationGreeting.tsxsrc/features/recommendations/components/RecommendationLetterCard.tsxsrc/features/recommendations/components/RecommendationLetterCarousel.tsxsrc/features/recommendations/components/RecommendationNews.tsxsrc/features/recommendations/components/RecommendationNoticePanel.tsxsrc/features/recommendations/components/RecommendationPendingContent.tsxsrc/features/recommendations/hooks/useRecommendationIntroAnimation.tssrc/pages/ExplorePage/ExplorePage.tsxsrc/pages/JobDetailPage/JobDetailPage.tsxsrc/pages/RecommendationsPage/RecommendationsPage.tsxsrc/routes/router.tsxsrc/styles/global.css
🚧 Files skipped from review as they are similar to previous changes (5)
- src/components/feedback/ResultIcon.tsx
- src/components/common/Tag.tsx
- src/features/onboarding/components/OnboardingProfileStep.tsx
- src/components/common/CarouselArrow.tsx
- src/components/layout/Header.tsx
| useEffect(() => { | ||
| if (!enableStackTransition) return; | ||
| if (activeContentRef.current.key === contentKey) return; | ||
|
|
||
| const nextContent = { key: contentKey, node: children }; | ||
| const direction = current >= previousCurrentRef.current ? 'forward' : 'backward'; | ||
| previousCurrentRef.current = current; | ||
| let transitionTimer: number | undefined; | ||
| const animationFrame = window.requestAnimationFrame(() => { | ||
| setTransitionDirection(direction); | ||
| setLeavingContent(activeContentRef.current.node); | ||
| activeContentRef.current = nextContent; | ||
| setActiveContent(nextContent); | ||
| transitionTimer = window.setTimeout(() => { | ||
| setLeavingContent(undefined); | ||
| setIsAnimating(false); | ||
| }, 440); | ||
| }); | ||
|
|
||
| return () => { | ||
| window.cancelAnimationFrame(animationFrame); | ||
| if (transitionTimer) window.clearTimeout(transitionTimer); | ||
| }; | ||
| }, [children, contentKey, current, enableStackTransition]); | ||
|
|
||
| const handlePrev = () => { | ||
| if (isAnimating || prevDisabled) return; | ||
|
|
||
| if (enableStackTransition) setIsAnimating(true); | ||
| onPrev?.(); | ||
| }; | ||
|
|
||
| const handleNext = () => { | ||
| if (isAnimating || nextDisabled) return; | ||
|
|
||
| if (enableStackTransition) setIsAnimating(true); | ||
| onNext?.(); | ||
| }; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
isAnimating이 화살표 클릭 경로에서만 설정되어, onSave/onDismiss로 트리거된 전환 중엔 화살표가 비활성화되지 않습니다.
RecommendationFlowContent.tsx의 저장/관심없음 버튼은 carousel의 handleNext를 거치지 않고 goNext()를 직접 호출합니다. 이때 전환 이펙트(라인 42-65)는 실행되지만 isAnimating은 여전히 false이므로 화살표가 활성 상태로 남습니다. 전환 중(440ms) 화살표를 빠르게 클릭하면 deckIndex가 두 번 진행되어 카드 한 장이 사용자에게 노출되지 않고 건너뛰어질 수 있습니다. isAnimating을 contentKey 변경을 감지하는 이펙트 내부에서 직접 설정하도록 옮기는 것을 권장합니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/features/recommendations/components/RecommendationLetterCarousel.tsx`
around lines 42 - 79, Move the isAnimating update into the contentKey-change
transition effect so every transition, including those triggered by onSave or
onDismiss, sets it before the animation begins and clears it after the existing
440ms timeout. Remove the arrow-only isAnimating assignments from handlePrev and
handleNext while preserving their guards and navigation behavior.
#️⃣ 연관된 이슈
📝 작업 내용
/login으로 연결하고,MainLayout레이아웃 셸과 라우터에 로그인/온보딩/정책/콜백/추천 라우트를 등록했습니다.RecommendationPendingPage에서RecommendationsPage로 이름을 바꿔, 이후 추천카드 도착 상태를 같은 라우트 안에서 분기 렌더링할 수 있는 구조로 정리했습니다(상태 분기 로직 자체는 이번 PR에 포함되지 않았습니다 — 관련 API가 아직 없습니다).components/common에서components/feedback으로 이동했습니다.cursor-pointer, Tag에selectvariant, CarouselArrow에 크기 variant, CarouselIndicator에 전환 애니메이션을 추가했습니다.src/styles/global.css로 분리했습니다.style타입을 추가하고, CodeRabbit 리뷰 지침을 보강했습니다.✅ 체크사항
📸 스크린샷 (UI 변경 시)
📦 추가한 라이브러리 (선택)
💬 리뷰 요구사항 (선택)
Summary by CodeRabbit
새 기능
개선
문서
style유형을 추가했습니다.