diff --git a/src/components/RecommendedTermCard.tsx b/src/components/RecommendedTermCard.tsx index 4a88a6e..01bb40b 100644 --- a/src/components/RecommendedTermCard.tsx +++ b/src/components/RecommendedTermCard.tsx @@ -1,4 +1,7 @@ +"use client"; + import React, { ElementType } from "react"; +import { useRouter } from "next/navigation"; // 1. 카테고리 아이콘 컴포넌트 임포트 (TagList.tsx와 동일한 Named Export 가정) import { CategoryAllIcon } from "@/components/icons/ic_category_all"; @@ -17,6 +20,7 @@ interface TermCardProps { category: string; description: string; iconColor: string; + slug: string; } // 2. 카테고리 이름과 아이콘 컴포넌트를 매핑 @@ -38,13 +42,22 @@ export default function RecommendedTermCard({ category, description, iconColor, + slug, }: TermCardProps) { + const router = useRouter(); // 3. 현재 카테고리에 맞는 아이콘 컴포넌트를 찾습니다. const IconComponent = CategoryIconMap[category] || CategoryAllIcon; + const handleClick = () => { + router.push(`/terms/${slug}`); + }; + return ( // Figma: w-64 p-5 rounded-xl outline outline-[0.25px] outline-offset-[-0.25px] outline-white -
+
diff --git a/src/components/RecommendedTermCardSkeleton.tsx b/src/components/RecommendedTermCardSkeleton.tsx new file mode 100644 index 0000000..4a73442 --- /dev/null +++ b/src/components/RecommendedTermCardSkeleton.tsx @@ -0,0 +1,22 @@ +export default function RecommendedTermCardSkeleton() { + return ( +
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+ ); +} diff --git a/src/components/search/RecommendedTermsSection.tsx b/src/components/search/RecommendedTermsSection.tsx index 5bc0d80..b1b48d9 100644 --- a/src/components/search/RecommendedTermsSection.tsx +++ b/src/components/search/RecommendedTermsSection.tsx @@ -2,6 +2,7 @@ import { useState, useEffect } from "react"; import RecommendedTermCard from "@/components/RecommendedTermCard"; +import RecommendedTermCardSkeleton from "@/components/RecommendedTermCardSkeleton"; import { ChevronsDownIcon } from "@/components/icons/ic_chevrons_down"; import { useAuth } from "@/contexts/AuthContext"; import { @@ -10,21 +11,28 @@ import { } from "@/lib/recommendations"; export default function RecommendedTermsSection() { - const { userData } = useAuth(); + const { userData, loading } = useAuth(); const [showMoreRecommended, setShowMoreRecommended] = useState(false); const [recommendedTerms, setRecommendedTerms] = useState( [] ); + const [isLoading, setIsLoading] = useState(true); useEffect(() => { const loadTerms = async () => { + if (loading) { + return; + } + + setIsLoading(true); const category = userData?.selectedCategory || "all"; const terms = await getRecommendedTerms(category, 6); setRecommendedTerms(terms); + setIsLoading(false); }; loadTerms(); - }, [userData?.selectedCategory]); + }, [userData, loading]); const displayedRecommendedTerms = showMoreRecommended ? recommendedTerms @@ -36,29 +44,42 @@ export default function RecommendedTermsSection() { 추천 용어
- {displayedRecommendedTerms.map((term, index) => ( - - ))} -
-
- + {isLoading ? ( + // 로딩 중일 때 스켈레톤 3개 표시 + <> + + + + + ) : ( + // 데이터 로드 완료 시 실제 카드 표시 + displayedRecommendedTerms.map((term, index) => ( + + )) + )}
+ {!isLoading && ( +
+ +
+ )} ); } diff --git a/src/lib/recommendations.ts b/src/lib/recommendations.ts index 348e267..fcef629 100644 --- a/src/lib/recommendations.ts +++ b/src/lib/recommendations.ts @@ -43,6 +43,7 @@ export interface RecommendedTerm { category: string; description: string; iconColor: string; + slug: string; } /** @@ -64,6 +65,7 @@ export async function getRecommendedTerms( category: categoryLabels[targetCategory], description: t.summary, iconColor: categoryColors[categoryId], + slug: t.slug, })); } @@ -78,6 +80,7 @@ export async function getRecommendedTerms( category: categoryLabels[targetCategory], description: t.summary, iconColor: categoryColors[categoryId], + slug: t.slug, })); } catch (error) { console.error("추천 용어 로드 실패:", error);