Skip to content

Conversation

@wantkdd
Copy link
Member

@wantkdd wantkdd commented Nov 30, 2025

✨ 작업 개요

검색화면 렌더링 오류 해결 및 클릭 시 용어 상세 연결

📌 관련 이슈

✅ 작업 내용

  • 검색화면 렌더링 오류 -> 스켈레톤 ui 도입
  • 추천 카드 클릭 시 용어 상세 페이지 연결

Summary by CodeRabbit

  • New Features
    • 추천 용어 카드 클릭 시 해당 용어의 상세 페이지로 이동하는 기능이 추가되었습니다.
    • 추천 용어 로딩 중에 스켈레톤 UI를 표시하여 로딩 상태를 시각적으로 개선했습니다.

✏️ Tip: You can customize this high-level summary in your review settings.

@wantkdd wantkdd self-assigned this Nov 30, 2025
@wantkdd wantkdd requested a review from a team as a code owner November 30, 2025 12:17
@wantkdd wantkdd added the 🛠 Fix 버그 수정 label Nov 30, 2025
@vercel
Copy link

vercel bot commented Nov 30, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
gotit Ready Ready Preview Comment Nov 30, 2025 0:17am

@coderabbitai
Copy link

coderabbitai bot commented Nov 30, 2025

Walkthrough

추천 용어 카드 컴포넌트에 클라이언트 라우팅 기능을 추가하고, 스켈레톤 로딩 UI를 도입하며, 로딩 상태를 관리하도록 수정했습니다. 추천 용어 데이터 모델에 slug 필드를 추가하여 라우팅에 활용합니다.

Changes

Cohort / File(s) Summary
추천 용어 카드 라우팅 추가
src/components/RecommendedTermCard.tsx
slug 프로퍼티 추가, next/navigation의 useRouter 훅 도입, 카드 클릭 시 /terms/{slug}로 네비게이션하는 onClick 핸들러 구현
스켈레톤 로딩 컴포넌트
src/components/RecommendedTermCardSkeleton.tsx
새 파일 생성, 펄스 애니메이션이 적용된 Tailwind 기반 스켈레톤 UI 렌더링
추천 용어 섹션 로딩 상태 관리
src/components/search/RecommendedTermsSection.tsx
isLoading 상태 추가, userData 의존성 변경, 로딩 중일 때 RecommendedTermCardSkeleton 3개 렌더링, 로드 완료 후 RecommendedTermCard에 slug 프로퍼티 전달, "더보기/접기" 컨트롤을 로딩 중이 아닐 때만 표시
추천 용어 데이터 모델 확장
src/lib/recommendations.ts
RecommendedTerm 인터페이스에 slug 필드 추가, getRecommendedTerms 함수에서 반환하는 모든 객체에 slug 값 포함

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • slug 프로퍼티가 여러 파일을 통해 일관되게 전달되는지 확인 필요
  • RecommendedTermsSection에서 로딩 상태 관리 로직의 정확성 검토 (userData 의존성 변경, useEffect 타이밍)
  • 스켈레톤 컴포넌트의 시각적 일관성 확인

Possibly related PRs

  • PR #29: RecommendedTermCard 컴포넌트를 처음 도입한 PR로, 이번 PR에서 해당 컴포넌트에 slug 프로퍼티와 라우팅 기능을 추가합니다.
  • PR #70: RecommendedTermsSection과 recommendations 데이터 구조를 함께 수정하는 관련 PR로, 본 PR에서도 동일한 영역의 slug 기반 라우팅 및 데이터 모델 확장이 이루어집니다.

Suggested labels

🚀 Feat, 🎨 Design

Poem

🐰 추천 카드에 길을 열어주고,
스켈레톤이 기다리는 로딩의 춤,
slug를 따라 /terms로 쏜살같이,
클릭 한 번에 네비게이션 완성!
버그도 잡고, 기능도 더했네 ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 검색화면 렌더링 오류 해결과 클릭 시 용어 상세 연결이라는 변경사항의 주요 내용을 명확하게 요약하고 있습니다.
Linked Issues check ✅ Passed PR의 모든 변경사항이 이슈 #83의 요구사항을 충족합니다: 스켈레톤 UI로 렌더링 오류 해결 및 useRouter를 통한 네비게이션 구현 완료.
Out of Scope Changes check ✅ Passed 모든 변경사항이 이슈 #83 범위 내에 있으며, 렌더링 오류 해결과 네비게이션 기능 추가에만 집중하고 있습니다.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/recommendations

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (6)
src/lib/recommendations.ts (1)

41-47: slug 필드에 대한 데이터 보장/방어 로직을 한 번 점검하는 게 좋습니다.

RecommendedTermslug: string을 필수로 추가하고, 두 분기에서 모두 t.slug를 그대로 노출하는 방향 자체는 PR 목적(카드 클릭 → 상세 페이지 이동)에 잘 맞습니다. 다만 getTermsByCategory가 반환하는 항목에 slug가 항상 채워져 있지 않다면 /terms/${slug}undefined 나 빈 문자열로 끝나는 경로가 생길 수 있습니다.

terms의 타입 정의에서 slug가 필수 string으로 이미 보장되는지 한 번 확인해 보시고, 혹시 선택 필드라면 t.slug가 falsy인 항목은 필터링하거나 폴백을 두는 식의 방어 로직을 추가하는 것을 권장합니다.

Also applies to: 61-69, 78-84

src/components/RecommendedTermCardSkeleton.tsx (1)

1-21: 스켈레톤 구조는 좋고, 접근성 측면에서 선택적 개선 여지가 있습니다.

실제 카드 레이아웃과 잘 맞춰진 스켈레톤이라 UI 측면에서는 무난해 보입니다. 다만 이 컴포넌트 자체에는 어떤 역할/aria 정보도 없어서, 상위 섹션에서 별도 로딩 상태 안내를 하지 않는 경우 스크린리더 사용자는 “무언가가 로딩 중”이라는 의미를 파악하기 어렵습니다.

  • 이 스켈레톤들을 단순 장식으로 취급한다면 aria-hidden="true"를 주고,
  • 대신 상위 RecommendedTermsSection 쪽에서 "추천 용어 로딩 중..." 같이 텍스트로 상태를 한 번만 읽어 주는 패턴을 고려해 볼 만합니다.

큰 이슈는 아니지만, 나중에 접근성 손볼 때 같이 정리해 두면 좋겠습니다.

src/components/RecommendedTermCard.tsx (1)

1-60: 카드 클릭 네비게이션은 목적에 부합하지만, 시맨틱/접근성 측면에서는 Link/버튼 사용을 권장합니다.

slug를 받아서 router.push(/terms/${slug})로 상세 페이지로 보내는 흐름은 이 PR의 요구사항을 잘 만족합니다. 다만 현재는 바깥 컨테이너가 단순 <div> + onClick 이라 키보드 포커스를 받을 수 없고, 화면 읽기 프로그램에서도 “클릭 가능한 요소”로 인식되기 어렵습니다.

가능한 개선 방향은 예를 들어 다음과 같습니다.

-import { useRouter } from "next/navigation";
+import Link from "next/link";

-export default function RecommendedTermCard({
-  term,
-  category,
-  description,
-  iconColor,
-  slug,
-}: TermCardProps) {
-  const router = useRouter();
-  const handleClick = () => {
-    router.push(`/terms/${slug}`);
-  };
-
-  return (
-    <div
-      onClick={handleClick}
-      className="flex w-64 cursor-pointer flex-col items-start justify-start gap-2.5 overflow-hidden rounded-xl bg-black/50 p-5 outline outline-[0.25px] outline-white/25 transition-colors hover:bg-black/70"
-    >
+export default function RecommendedTermCard({
+  term,
+  category,
+  description,
+  iconColor,
+  slug,
+}: TermCardProps) {
+  return (
+    <Link
+      href={`/terms/${slug}`}
+      className="flex w-64 cursor-pointer flex-col items-start justify-start gap-2.5 overflow-hidden rounded-xl bg-black/50 p-5 outline outline-[0.25px] outline-white/25 transition-colors hover:bg-black/70"
+    >
       {/* ...나머지 내용 동일... */}
-    </div>
+    </Link>
   );
}

이렇게 하면:

  • 기본적으로 키보드 포커스/엔터 키로도 동작하고,
  • Next.js의 <Link> 프리페치 이점도 같이 얻을 수 있습니다.

현재 구현도 동작은 하지만, 이후 접근성/SEO를 고려하면 위와 같이 정리해 두는 것을 추천드립니다.

src/components/search/RecommendedTermsSection.tsx (3)

19-37: userData가 끝까지 null일 수 있는 경우 스켈레톤이 영구 로딩 상태로 남을 수 있습니다.

useEffect 안에서 !userData이면 그냥 return 하고 있어서, 로그인 실패/게스트 모드 등으로 userData가 최종적으로도 null인 시나리오가 있다면 isLoading이 계속 true로 남고 스켈레톤 3개가 무한히 떠 있게 됩니다.

앱 구조상 userData가 항상 곧 초기화되는 것이 보장된다면 그대로 둬도 되지만, 혹시 그렇지 않다면:

  • userData가 없을 때는 추천 섹션 자체를 렌더링하지 않거나 (if (!userData) return null;),
  • 혹은 userData 없이도 category = "all"getRecommendedTerms를 호출해 게스트용 추천을 보여주는

등의 분기 처리를 넣는 쪽이 UX 측면에서 더 안전해 보입니다. 실제 useAuth 동작을 한 번 점검해 보시는 걸 추천드립니다.


57-66: 리스트 key로 index 대신 term.slug를 사용하는 편이 더 안전합니다.

추천 용어 배열은 크게 변동이 없겠지만, 현재 key={index}를 쓰고 있어서 순서 변경/부분 업데이트가 생기면 리렌더링 측면에서 React가 의도치 않게 DOM을 재사용할 수 있습니다. 이 카드에는 고유 식별자인 slug가 있으니, 가능하면 이를 key로 쓰는 게 좋습니다.

-          displayedRecommendedTerms.map((term, index) => (
-            <RecommendedTermCard
-              key={index}
+          displayedRecommendedTerms.map((term) => (
+            <RecommendedTermCard
+              key={term.slug}
               term={term.term}
               category={term.category}
               description={term.description}
               iconColor={term.iconColor}
               slug={term.slug}
             />
           ))

지금 당장 큰 문제는 아니지만, 이후 추천 목록이 동적으로 바뀌는 요구사항이 생길 때를 대비해 미리 정리해 두면 좋을 것 같습니다.


48-55: 추천 용어 개수에 따라 ‘더보기/접기’ 버튼 노출 조건을 조정하면 UX가 더 자연스러울 것 같습니다.

현재 구현에서는 !isLoading이기만 하면 추천 용어가 0개이거나 최대 3개뿐이어도 더보기/접기 버튼이 항상 노출될 수 있습니다. 이 경우 버튼을 눌러도 UI 변화가 없어서 사용자 입장에서는 헷갈릴 수 있습니다.

추천 용어가 3개를 초과할 때만 버튼을 노출하도록 조건을 조금 더 좁혀보는 것을 제안드립니다.

-      {!isLoading && (
+      {!isLoading && recommendedTerms.length > 3 && (
         <div className="flex flex-col items-center justify-center gap-2.5 self-stretch overflow-hidden pt-5">
           <button
             onClick={() => setShowMoreRecommended(!showMoreRecommended)}
             className="inline-flex items-center justify-center gap-1 text-sm font-bold text-neutral-300 transition-colors hover:text-white"
           >
             <ChevronsDownIcon
               className={`h-4 w-4 transition-transform ${showMoreRecommended ? "rotate-180" : ""}`}
               width={16}
               height={16}
             />
             {showMoreRecommended ? "접기" : "더보기"}
           </button>
         </div>
       )}

이렇게 하면 실제로 “더 보기”가 가능한 상황에서만 버튼이 나타나 더 직관적인 동작이 됩니다.

Also applies to: 69-83

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 77ebfe7 and dc4d3ff.

📒 Files selected for processing (4)
  • src/components/RecommendedTermCard.tsx (3 hunks)
  • src/components/RecommendedTermCardSkeleton.tsx (1 hunks)
  • src/components/search/RecommendedTermsSection.tsx (3 hunks)
  • src/lib/recommendations.ts (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/components/RecommendedTermCard.tsx (1)
src/components/icons/ic_category_all.tsx (1)
  • CategoryAllIcon (3-25)
src/components/search/RecommendedTermsSection.tsx (3)
src/lib/recommendations.ts (1)
  • getRecommendedTerms (52-89)
src/components/RecommendedTermCardSkeleton.tsx (1)
  • RecommendedTermCardSkeleton (1-22)
src/components/RecommendedTermCard.tsx (1)
  • RecommendedTermCard (40-93)

@wantkdd wantkdd merged commit 4357d79 into develop Nov 30, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🛠 Fix 버그 수정

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] 검색화면 렌더링 오류 및 네비게이션 추가

2 participants