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) => (
-
- ))}
-
-
- setShowMoreRecommended(!showMoreRecommended)}
- className="inline-flex items-center justify-center gap-1 text-sm font-bold text-neutral-300 transition-colors hover:text-white"
- >
-
- {showMoreRecommended ? "접기" : "더보기"}
-
+ {isLoading ? (
+ // 로딩 중일 때 스켈레톤 3개 표시
+ <>
+
+
+
+ >
+ ) : (
+ // 데이터 로드 완료 시 실제 카드 표시
+ displayedRecommendedTerms.map((term, index) => (
+
+ ))
+ )}
+ {!isLoading && (
+
+ setShowMoreRecommended(!showMoreRecommended)}
+ className="inline-flex items-center justify-center gap-1 text-sm font-bold text-neutral-300 transition-colors hover:text-white"
+ >
+
+ {showMoreRecommended ? "접기" : "더보기"}
+
+
+ )}
);
}
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);