-
Notifications
You must be signed in to change notification settings - Fork 1
[Feat] 소비자 소비 유형 기반 맞춤 금융상품 추천 필터링 로직 구현 #66
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
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
|
""" Walkthrough이 변경사항은 금융 상품 추천 및 소비자 탭 관련 페이지와 컴포넌트의 렌더링 및 데이터 흐름을 개선합니다. 상품 타입 및 카테고리 표기 방식이 변경되었고, 상품 리스트는 리뷰 수 기준으로 정렬됩니다. 새로운 로그인 모달 컴포넌트가 추가되었으며, 카테고리 명칭 일관성도 확보되었습니다. Changes
Possibly related PRs
Suggested reviewers
Tip ⚡️ Faster reviews with caching
Enjoy the performance boost—your workflow just got faster. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (9)
✅ Files skipped from review due to trivial changes (3)
🚧 Files skipped from review as they are similar to previous changes (6)
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
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: 3
🧹 Nitpick comments (5)
src/pages/support/components/HaveToLoginModal.jsx (1)
1-55: 필요한 특성들이 모두 구현된 잘 작성된 모달 컴포넌트입니다.로그인 요구 모달 컴포넌트가 명확하게 구현되어 있으며, props를 통한 유연한 설정이 가능합니다. 다만 몇 가지 개선 사항을 제안합니다:
- 접근성 향상을 위한 ARIA 속성 추가
- 키보드 이벤트 처리 (예: Escape 키로 모달 닫기)
- 로그인 경로 하드코딩 대신 기본값이 있는 prop으로 받기
모달의 접근성을 향상시키기 위해 다음과 같은 변경사항을 적용해보세요:
<div - className="fixed inset-0 z-[10001] flex justify-center items-center bg-black bg-opacity-30"> + className="fixed inset-0 z-[10001] flex justify-center items-center bg-black bg-opacity-30" + role="dialog" + aria-modal="true" + onKeyDown={(e) => e.key === 'Escape' && onClose()}>그리고 로그인 경로를 더 유연하게 만들기 위해:
const HaveToLoginModal = ({ message, subMessage, onClose, showButton = true, showClose = true, + loginPath = "/auth", }) => { const navigate = useNavigate(); const handleLogin = () => { onClose(); - navigate("/auth"); + navigate(loginPath); };src/pages/support/SupportPage.jsx (1)
67-77: 조건부 렌더링이 명확하게 처리되었습니다.로그인 상태에 따른 컴포넌트 렌더링 로직이 적절히 구현되어 있습니다. 사용자가 로그인하지 않은 경우 ConsumerTab 대신 HaveToLoginModal을 표시하고, 로그인 상태 확인 중에는 아무것도 표시하지 않습니다.
로딩 상태(isLoggedIn이 null일 때)에 대한 처리를 개선할 수 있습니다:
{category === "consumer" && - (isLoggedIn === null ? null : isLoggedIn ? ( + (isLoggedIn === null ? ( + <div className="flex justify-center items-center h-64"> + <p className="text-gray-6">로그인 상태 확인 중...</p> + </div> + ) : isLoggedIn ? ( <ConsumerTab /> ) : ( <HaveToLoginModal message="로그인이 필요한 기능입니다" subMessage="소비 가치 확인을 위해 로그인해주세요" showButton onClose={() => handleTabChange("company")} /> ))}src/pages/support/components/RecommendationCard.jsx (1)
34-46: 카테고리 표시 로직이 개선되었습니다.상품 유형과 카테고리 표시 로직이 향상되었으나, FinancialProductDetailPage와 마찬가지로 세 필드가 모두 존재하는 경우에만 표시됩니다. 일부 상품에는 모든 필드가 없을 수 있습니다.
제안사항: 가능한 경우 조건부 로직을 보다 유연하게 만들어 일부 필드만 있는 경우에도 해당 정보를 표시하는 것이 좋습니다.
-{productType && recommendedCategory && defaultCategory && ( +{(productType || recommendedCategory || defaultCategory) && ( <> - <span className="text-caption2 font-medium text-error bg-errorContainer px-2 py-1 rounded"> - {productType} - </span> - <span className="text-caption2 font-medium text-secondary bg-secondaryBackground px-2 py-1 rounded"> - {recommendedCategory} - </span> - <span className="text-caption2 font-medium text-secondary bg-secondaryBackground px-2 py-1 rounded"> - {defaultCategory} - </span> + {productType && ( + <span className="text-caption2 font-medium text-error bg-errorContainer px-2 py-1 rounded"> + {productType} + </span> + )} + {recommendedCategory && ( + <span className="text-caption2 font-medium text-secondary bg-secondaryBackground px-2 py-1 rounded"> + {recommendedCategory} + </span> + )} + {defaultCategory && ( + <span className="text-caption2 font-medium text-secondary bg-secondaryBackground px-2 py-1 rounded"> + {defaultCategory} + </span> + )} </> )}src/pages/support/components/ConsumerTab.jsx (1)
24-31: 카테고리 기반 필터링 로직 추가소비 패턴 기반으로 금융 상품을 필터링하는 로직을 구현했습니다. 선택된 topCategory가 있을 경우 각 상품의 recommendedCategory 또는 defaultCategory와 일치하는지 확인합니다.
성능 최적화를 위해 useMemo를 사용하여 filteredProducts를 메모이제이션하는 것이 좋을 것 같습니다.
- const filteredProducts = topCategory - ? safeProducts.filter( - (item) => - item.recommendedCategory === ENUM_TO_KOR_MAP[topCategory] || - item.defaultCategory === ENUM_TO_KOR_MAP[topCategory] - ) - : safeProducts; + const filteredProducts = useMemo(() => { + return topCategory + ? safeProducts.filter( + (item) => + item.recommendedCategory === ENUM_TO_KOR_MAP[topCategory] || + item.defaultCategory === ENUM_TO_KOR_MAP[topCategory] + ) + : safeProducts; + }, [safeProducts, topCategory, ENUM_TO_KOR_MAP]);src/pages/support/FinancialProductListPage.jsx (1)
83-96: RecommendationCard에 카테고리 props 추가RecommendationCard 컴포넌트에 recommendedCategory와 defaultCategory props를 전달합니다. 이를 통해 카드 컴포넌트가 카테고리 정보를 활용할 수 있습니다.
map 함수에서 사용되지 않는 두 번째 인자는 제거하거나 명확한 이름을 사용하는 것이 좋습니다.
- {safeProducts.map((item) => ( + {safeProducts.map((item) => (또는
- {safeProducts.map((item, _) => ( + {safeProducts.map((item, index) => (
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
public/svgs/support/consumer/Ic_Alert.svgis excluded by!**/*.svg
📒 Files selected for processing (8)
src/pages/support/FinancialProductDetailPage.jsx(1 hunks)src/pages/support/FinancialProductListPage.jsx(3 hunks)src/pages/support/SupportPage.jsx(1 hunks)src/pages/support/components/ConsumerTab.jsx(5 hunks)src/pages/support/components/ConsumptionChart.jsx(4 hunks)src/pages/support/components/HaveToLoginModal.jsx(1 hunks)src/pages/support/components/RecommendationCard.jsx(2 hunks)src/pages/support/constants/consumerMap.js(3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/pages/support/FinancialProductListPage.jsx (1)
src/components/common/Spinner.jsx (1)
Spinner(3-9)
🔇 Additional comments (19)
src/pages/support/constants/consumerMap.js (3)
15-15: 카테고리 이름이 일관성 있게 변경되었습니다."예비"에서 "예비형"으로의 변경은 다른 카테고리 명명 규칙(~형)과 일치하도록 보입니다. 이 변경은 UI 전반에 걸쳐 일관된 사용자 경험을 제공할 것입니다.
24-24: 일관된 카테고리 매핑 업데이트.KOR_TO_ENUM_MAP에서 "예비"에서 "예비형"으로의 키 변경은 SPEECH_BUBBLE_MAP의 변경사항과 일치합니다.
33-33: 양방향 매핑이 올바르게 업데이트되었습니다."PRE" enum 값에 대한 한국어 이름이 "예비"에서 "예비형"으로 일관되게 변경되었습니다. 이 변경으로 KOR_TO_ENUM_MAP과 ENUM_TO_KOR_MAP 간의 양방향 매핑이 유지됩니다.
src/pages/support/FinancialProductDetailPage.jsx (1)
63-77:Details
❓ Verification inconclusive
카테고리 표시 로직이 강화되었습니다.
상품 유형과 카테고리 표시 로직이 개선되었습니다. 이제 productType, recommendedCategory, defaultCategory 세 필드가 모두 존재해야 표시됩니다. 각 카테고리는 서로 다른 스타일로 렌더링되어 사용자가 쉽게 구분할 수 있습니다.
그러나 모든 필드가 필요하다는 조건이 너무 제한적일 수 있습니다. 일부 상품에는 세 필드 중 하나 또는 두 개만 존재할 수 있으며, 이 경우에는 아무것도 표시되지 않습니다.
다음 스크립트를 실행하여 데이터에 항상 세 필드가 모두 존재하는지 확인해보세요:
🏁 Script executed:
#!/bin/bash # 금융 상품 데이터에서 필수 필드 존재 여부 확인 # 금융 상품 API 호출 또는 상품 데이터 파일 분석 rg -A 5 "productType|recommendedCategory|defaultCategory" --type jsLength of output: 7025
카테고리 렌더링 조건 완화 검토 요청
현재
productType,recommendedCategory,defaultCategory세 필드가 모두 있어야만 렌더링되므로 일부 필드만 있는 상품은 UI가 비어보일 수 있습니다.
다음 위치에서 해당 로직을 사용 중입니다:
src/pages/support/FinancialProductDetailPage.jsx(63–77라인)src/pages/support/components/RecommendationCard.jsx- 유사 조건:
FinancialProductListPage.jsx및ConsumerTab.jsxAPI 스펙이나 실제 데이터에서 세 필드가 항상 제공되는지 검증하거나, 아래 예시처럼 개별 필드가 존재할 때만 렌더링하도록 로직을 완화하는 방안을 검토해주세요:
- {data.productType && data.recommendedCategory && data.defaultCategory && ( - <> - <span className="text-caption2 font-medium text-error bg-errorContainer px-2 py-1 rounded"> - {data.productType} - </span> - <span className="text-caption2 font-medium text-secondary bg-secondaryBackground px-2 py-1 rounded"> - {data.recommendedCategory} - </span> - <span className="text-caption2 font-medium text-secondary bg-secondaryBackground px-2 py-1 rounded"> - {data.defaultCategory} - </span> - </> - )} + <> + {data.productType && ( + <span className="text-caption2 font-medium text-error bg-errorContainer px-2 py-1 rounded"> + {data.productType} + </span> + )} + {data.recommendedCategory && ( + <span className="text-caption2 font-medium text-secondary bg-secondaryBackground px-2 py-1 rounded"> + {data.recommendedCategory} + </span> + )} + {data.defaultCategory && ( + <span className="text-caption2 font-medium text-secondary bg-secondaryBackground px-2 py-1 rounded"> + {data.defaultCategory} + </span> + )} + </>src/pages/support/components/ConsumptionChart.jsx (4)
12-12: 컴포넌트 API가 확장되었습니다.새로운
onTopCategory콜백 프롭이 추가되어 부모 컴포넌트와의 상호작용이 가능해졌습니다. 이를 통해 최상위 카테고리 정보를 상위 컴포넌트로 전달할 수 있습니다.
54-54: 데이터 구조 개선.각 데이터 항목에
companyType필드를 추가하여 상위 컴포넌트에서 활용할 수 있게 되었습니다.
68-71: 최상위 카테고리 콜백 기능 구현.최상위 카테고리가 존재하는 경우에만
onTopCategory콜백을 호출하는 조건부 로직이 적절히 구현되었습니다. 이는 PR 목표에 부합하는 변경사항입니다.
85-85: 의존성 배열 적절하게 업데이트.
useEffect의존성 배열에onTopCategory가 추가되어 콜백이 변경될 때 효과가 적절히 재실행됩니다. 이는 React의 베스트 프랙티스를 따르는 변경입니다.src/pages/support/components/RecommendationCard.jsx (1)
9-10: props API가 개선되었습니다.
benefitprop 대신recommendedCategory와defaultCategoryprops를 추가하여 더 구체적인 카테고리 정보를 표시할 수 있게 되었습니다. 이는 FinancialProductDetailPage와의 일관성을 유지합니다.src/pages/support/components/ConsumerTab.jsx (6)
9-9: 새로운 상수 맵 ENUM_TO_KOR_MAP 추가언어 상수 매핑을 위한 ENUM_TO_KOR_MAP을 import하여 카테고리 변환에 활용하고 있습니다. 이 상수를 통해 리뷰의 companyType을 한국어 카테고리명으로 변환하는 것으로 보입니다.
12-12: 상태 추가: topCategory사용자의 소비 패턴에서 상위 카테고리를 추적하기 위한 상태를 추가했습니다. 이 상태는 ConsumptionChart에서 가장 많은 비율을 차지하는 카테고리를 저장하는 데 사용됩니다.
22-23: 배열 안전 처리consumerProducts가 배열인지 확인하고 안전하게 처리하는 코드를 추가했습니다. API 응답이 예상과 다를 경우 오류를 방지하는 데 도움이 됩니다.
50-50: ConsumptionChart에 onTopCategory prop 추가ConsumptionChart 컴포넌트에 onTopCategory prop을 전달하여 사용자의 소비 패턴에서 최상위 카테고리를 설정할 수 있게 했습니다. 이를 통해 차트 컴포넌트가 부모 컴포넌트의 상태를 업데이트할 수 있습니다.
67-67: filteredProducts를 사용하도록 변경기존 safeProducts 대신 필터링된 상품 목록인 filteredProducts를 사용하도록 변경했습니다. 이는 사용자의 소비 패턴에 맞는 상품만 표시하기 위한 변경입니다.
77-79: RecommendationCard에 카테고리 props 추가RecommendationCard 컴포넌트에 recommendedCategory와 defaultCategory props를 전달합니다. 이를 통해 카드 컴포넌트가 카테고리 정보를 활용할 수 있습니다.
이 props가 RecommendationCard 컴포넌트에서 올바르게 활용되는지 확인하세요.
src/pages/support/FinancialProductListPage.jsx (4)
6-7: API와 상수 맵 import 추가리뷰 수에 따라 상품을 정렬하기 위해 소비 데이터를 가져오는 API와 카테고리 매핑을 위한 상수를 추가했습니다. 이는 금융 상품을 리뷰 수에 따라 정렬하는 기능을 지원합니다.
13-14: 정렬된 상품 목록을 위한 상태 추가리뷰 수에 따라 정렬된 상품 목록을 저장하기 위한 상태를 추가했습니다. 이를 통해 사용자에게 더 관련성 높은 상품을 먼저 표시할 수 있습니다.
60-60: 정렬된 상품 배열 안전 처리sortedProducts가 배열인지 확인하고 안전하게 처리하는 코드를 추가했습니다. API 응답이 예상과 다를 경우 오류를 방지하는 데 도움이 됩니다.
74-77: 정렬 기준 안내 메시지 추가사용자에게 상품이 리뷰 수에 따라 정렬되었음을 알리는 메시지를 추가했습니다. 이는 좋은 UX 관행으로 사용자가 정렬 기준을 이해하는 데 도움이 됩니다.
| import ConsumerTab from "@/pages/support/components/ConsumerTab"; | ||
| import HaveToLoginModal from "@components/common/HaveToLoginModal"; | ||
| import { getMyProfile } from "@apis/member/auth"; | ||
| import HaveToLoginModal from "./components/HaveToLoginModal"; |
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.
💡 Verification agent
🧩 Analysis chain
HaveToLoginModal 컴포넌트 경로 변경이 적절히 이루어졌습니다.
컴포넌트의 위치가 공용 디렉토리에서 지원 페이지 전용 디렉토리로 이동된 것으로 보입니다. 이는 해당 모달이 지원 페이지에서만 사용된다는 의도를 명확히 합니다.
🏁 Script executed:
#!/bin/bash
# 다른 파일에서 이전 경로의 HaveToLoginModal import 문이 있는지 확인
rg "@components/common/HaveToLoginModal" --type js --type jsxLength of output: 89
🏁 Script executed:
#!/bin/bash
# 다른 파일에서 이전 경로의 HaveToLoginModal import 문이 있는지 재확인
rg "@components/common/HaveToLoginModal" -g '*.js' -g '*.jsx'Length of output: 366
HaveToLoginModal 경로 일괄 업데이트 필요
지원 페이지 외 다른 파일들이 아직 이전 @components/common/HaveToLoginModal 경로를 참조하고 있어, 빌드 에러가 발생할 수 있습니다. 아래 파일들의 import 문을 새로운 위치(예: ../support/components/HaveToLoginModal)로 변경해 주세요.
• src/pages/search/SearchPage.jsx
- import HaveToLoginModal from "@components/common/HaveToLoginModal";
+ import HaveToLoginModal from "../support/components/HaveToLoginModal";• src/pages/story/components/StoryDetail.jsx
- import HaveToLoginModal from "@components/common/HaveToLoginModal";
+ import HaveToLoginModal from "../../support/components/HaveToLoginModal";• src/pages/map/MapPage.jsx
- import HaveToLoginModal from "@components/common/HaveToLoginModal";
+ import HaveToLoginModal from "../support/components/HaveToLoginModal";위와 같이 모든 참조를 일관되게 업데이트한 후 다시 검증 부탁드립니다.
Committable suggestion skipped: line range outside the PR's diff.
| </div> | ||
|
|
||
| {isLoading && <Spinner />} | ||
| {(isLoading || safeProducts.length === 0) && <Spinner />} |
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.
🛠️ Refactor suggestion
로딩 상태 처리 개선
로딩 상태 확인 조건을 수정하여 isLoading이 true이거나 safeProducts가 비어 있을 때 스피너를 표시합니다. 그러나 이 조건은 실제로 상품이 없는 경우와 로딩 중인 경우를 구분하지 못합니다.
- {(isLoading || safeProducts.length === 0) && <Spinner />}
+ {isLoading ? (
+ <Spinner />
+ ) : (
+ safeProducts.length === 0 && (
+ <div className="w-full py-8 text-center text-gray-7">
+ 표시할 금융 상품이 없습니다.
+ </div>
+ )
+ )}| useEffect(() => { | ||
| const sortProductsByReviewCount = async () => { | ||
| if (!products || products.length === 0) return; | ||
|
|
||
| const uniqueCategories = new Set(); | ||
| products.forEach((item) => { | ||
| if (item.recommendedCategory) | ||
| uniqueCategories.add(item.recommendedCategory); | ||
| if (item.defaultCategory) uniqueCategories.add(item.defaultCategory); | ||
| }); | ||
|
|
||
| const reviewCountMap = new Map(); | ||
|
|
||
| await Promise.all( | ||
| [...uniqueCategories].map(async (korName) => { | ||
| const enumKey = KOR_TO_ENUM_MAP[korName]; | ||
| if (!enumKey) return; | ||
|
|
||
| try { | ||
| const res = await getConsumptionDetail(enumKey); | ||
| reviewCountMap.set(korName, res?.reviewCount || 0); | ||
| } catch { | ||
| reviewCountMap.set(korName, 0); | ||
| } | ||
| }) | ||
| ); | ||
|
|
||
| const sorted = [...products].sort((a, b) => { | ||
| const aCount = | ||
| reviewCountMap.get(a.recommendedCategory) || | ||
| reviewCountMap.get(a.defaultCategory) || | ||
| 0; | ||
| const bCount = | ||
| reviewCountMap.get(b.recommendedCategory) || | ||
| reviewCountMap.get(b.defaultCategory) || | ||
| 0; | ||
| return bCount - aCount; | ||
| }); | ||
|
|
||
| setSortedProducts(sorted); | ||
| }; | ||
|
|
||
| sortProductsByReviewCount(); | ||
| }, [products]); |
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.
🛠️ Refactor suggestion
상품 정렬 로직 구현
리뷰 수에 따라 금융 상품을 정렬하는 로직을 useEffect 내에 구현했습니다. 고유한 카테고리를 추출하고 각 카테고리의 리뷰 수를 가져온 다음, 이 데이터를 기반으로 상품을 정렬합니다.
몇 가지 개선 사항이 있습니다:
- API 호출 실패 시 에러 로깅이나 사용자 피드백이 없습니다.
- 중복 API 호출을 최소화하기 위한 캐싱 메커니즘이 없습니다.
useEffect(() => {
const sortProductsByReviewCount = async () => {
if (!products || products.length === 0) return;
const uniqueCategories = new Set();
products.forEach((item) => {
if (item.recommendedCategory)
uniqueCategories.add(item.recommendedCategory);
if (item.defaultCategory) uniqueCategories.add(item.defaultCategory);
});
const reviewCountMap = new Map();
+ // 로컬 스토리지를 통한 간단한 캐싱 구현
+ const cachedReviewCounts = localStorage.getItem('categoryReviewCounts');
+ const cachedData = cachedReviewCounts ? JSON.parse(cachedReviewCounts) : {};
+ const cacheTimestamp = localStorage.getItem('categoryReviewCountsTimestamp');
+ const isCacheValid = cacheTimestamp && (Date.now() - parseInt(cacheTimestamp)) < 3600000; // 1시간 캐시
await Promise.all(
[...uniqueCategories].map(async (korName) => {
const enumKey = KOR_TO_ENUM_MAP[korName];
if (!enumKey) return;
+ // 유효한 캐시가 있으면 사용
+ if (isCacheValid && cachedData[korName] !== undefined) {
+ reviewCountMap.set(korName, cachedData[korName]);
+ return;
+ }
try {
const res = await getConsumptionDetail(enumKey);
reviewCountMap.set(korName, res?.reviewCount || 0);
+ // 캐시 업데이트
+ cachedData[korName] = res?.reviewCount || 0;
} catch (error) {
+ console.error(`카테고리 ${korName}의 리뷰 수를 가져오는 중 오류 발생:`, error);
reviewCountMap.set(korName, 0);
+ // 캐시에 0 설정
+ cachedData[korName] = 0;
}
})
);
+ // 캐시 저장
+ localStorage.setItem('categoryReviewCounts', JSON.stringify(cachedData));
+ localStorage.setItem('categoryReviewCountsTimestamp', Date.now().toString());
const sorted = [...products].sort((a, b) => {
const aCount =
reviewCountMap.get(a.recommendedCategory) ||
reviewCountMap.get(a.defaultCategory) ||
0;
const bCount =
reviewCountMap.get(b.recommendedCategory) ||
reviewCountMap.get(b.defaultCategory) ||
0;
return bCount - aCount;
});
setSortedProducts(sorted);
};
sortProductsByReviewCount();
}, [products]);Committable suggestion skipped: line range outside the PR's diff.
|
금융 상품 정렬 페이지에 리뷰 건수가 많은 순서대로 정렬되어 있다고 하는 멘트가 좀 이해하기 어려운 것 같아요! 금융상품에 사용자들이 리뷰를 달았다는 건가..? 싶을 것 같아서 좀더 명확한 멘트로 변경하는 것이 좋을 것 같습니다. |
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: 0
♻️ Duplicate comments (1)
src/pages/support/FinancialProductListPage.jsx (1)
97-97: 🛠️ Refactor suggestion로딩 상태 처리 개선 필요
로딩 상태와 데이터 없음 상태를 구분하지 않고 있어, 사용자가 실제로 상품이 없는 것인지 아직 로딩 중인 것인지 알 수 없습니다.
로딩 상태와 데이터 없음 상태를 명확히 구분하여 표시하는 것이 좋습니다:
- {(isLoading || safeProducts.length === 0) && <Spinner />} + {isLoading ? ( + <Spinner /> + ) : ( + safeProducts.length === 0 && ( + <div className="w-full py-8 text-center text-gray-7"> + 표시할 금융 상품이 없습니다. + </div> + ) + )}
🧹 Nitpick comments (2)
src/pages/support/FinancialProductListPage.jsx (2)
30-73: 리뷰 수에 따른 금융 상품 정렬 로직소비 유형별 리뷰 수에 따라 금융 상품을 정렬하는 기능이 구현되었습니다. 다만, 몇 가지 개선할 수 있는 부분이 있습니다:
- API 호출 실패 시 사용자에게 피드백을 제공하지 않고 있습니다.
- 카테고리별 리뷰 수를 캐싱하는 메커니즘이 없어 성능 이슈가 발생할 수 있습니다.
리뷰 수 데이터를 캐싱하여 성능을 개선할 수 있습니다:
useEffect(() => { const sortProductsByReviewCount = async () => { if (!products || products.length === 0) return; const uniqueCategories = new Set(); products.forEach((item) => { if (item.recommendedCategory) uniqueCategories.add(item.recommendedCategory); if (item.defaultCategory) uniqueCategories.add(item.defaultCategory); }); const reviewCountMap = new Map(); + // 로컬 스토리지를 통한 간단한 캐싱 구현 + const cachedReviewCounts = localStorage.getItem('categoryReviewCounts'); + const cachedData = cachedReviewCounts ? JSON.parse(cachedReviewCounts) : {}; + const cacheTimestamp = localStorage.getItem('categoryReviewCountsTimestamp'); + const isCacheValid = cacheTimestamp && (Date.now() - parseInt(cacheTimestamp)) < 3600000; // 1시간 캐시 await Promise.all( [...uniqueCategories].map(async (korName) => { const enumKey = KOR_TO_ENUM_MAP[korName]; if (!enumKey) return; + // 유효한 캐시가 있으면 사용 + if (isCacheValid && cachedData[korName] !== undefined) { + reviewCountMap.set(korName, cachedData[korName]); + return; + } try { const res = await getConsumptionDetail(enumKey); reviewCountMap.set(korName, res?.reviewCount || 0); + // 캐시 업데이트 + cachedData[korName] = res?.reviewCount || 0; } catch (error) { + console.error(`카테고리 ${korName}의 리뷰 수를 가져오는 중 오류 발생:`, error); reviewCountMap.set(korName, 0); + // 캐시에 0 설정 + cachedData[korName] = 0; } }) ); + // 캐시 저장 + localStorage.setItem('categoryReviewCounts', JSON.stringify(cachedData)); + localStorage.setItem('categoryReviewCountsTimestamp', Date.now().toString()); // 나머지 코드는 동일...
89-94: 맞춤형 상품 정렬 메시지 추가사용자 이름을 활용한 맞춤형 메시지를 추가하여 사용자 경험을 개선했습니다. 다만, PR 코멘트에서 언급된 것처럼 이 메시지가 명확하지 않을 수 있습니다.
메시지를 더 명확하게 수정하는 것이 좋을 것 같습니다:
<p className="caption2 text-primary-8"> - {userName}님이 리뷰를 남긴 기업 특성과 연관된 금융상품 순으로 - 보여드려요! + {userName}님의 소비 패턴과 관련성이 높은 금융상품을 우선적으로 + 보여드립니다! </p>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
public/svgs/support/consumer/Ic_SupportMessage.svgis excluded by!**/*.svg
📒 Files selected for processing (5)
src/pages/support/FinancialProductListPage.jsx(3 hunks)src/pages/support/components/ConsumerTab.jsx(4 hunks)src/pages/support/components/RecommendationCard.jsx(3 hunks)src/pages/support/constants/consumerMap.js(3 hunks)tailwind.config.js(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- tailwind.config.js
🚧 Files skipped from review as they are similar to previous changes (3)
- src/pages/support/components/ConsumerTab.jsx
- src/pages/support/components/RecommendationCard.jsx
- src/pages/support/constants/consumerMap.js
🔇 Additional comments (5)
src/pages/support/FinancialProductListPage.jsx (5)
6-8: API 임포트 추가getConsumptionDetail과 getMyProfile API를 추가하여 소비 유형과 사용자 정보를 가져오는 기능이 구현되었습니다. KOR_TO_ENUM_MAP도 추가하여 한글 카테고리명과 enum 값을 매핑하는 기능이 추가되었습니다.
13-14: 사용자 이름 상태 변수 추가사용자 이름을 저장하기 위한 상태 변수가 추가되었습니다. 이는 맞춤형 메시지를 표시하는 데 사용될 예정입니다.
15-26: 사용자 프로필 데이터 가져오기컴포넌트 마운트 시 사용자 프로필을 비동기적으로 가져오는 로직이 구현되었습니다. 오류 처리도 적절히 되어 있습니다.
28-29: 정렬된 상품 목록을 위한 상태 변수 추가리뷰 수에 따라 정렬된 금융 상품 목록을 저장하기 위한 상태 변수가 추가되었습니다.
101-113: RecommendationCard에 카테고리 정보 전달금융 상품 카드에 카테고리 정보를 전달하여 PR 목표인 "소비자 소비 유형 기반 맞춤 금융상품 추천 필터링 로직"을 구현하였습니다. 이를 통해 사용자의 소비 패턴에 맞는 금융 상품을 추천할 수 있게 되었습니다.
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
♻️ Duplicate comments (2)
src/pages/support/FinancialProductListPage.jsx (2)
30-73: 🛠️ Refactor suggestion카테고리 리뷰 기반 정렬 로직 성능 및 안정성 개선 필요
상품 정렬 로직이 잘 구현되었지만, 몇 가지 개선 사항이 있습니다:
- API 호출 결과를 캐싱하지 않아 불필요한 네트워크 요청이 발생할 수 있습니다.
- API 호출 에러에 대한 사용자 피드백이 없습니다.
- 카테고리가 많은 경우 병렬 API 요청이 많아질 수 있으므로 제한이 필요할 수 있습니다.
다음과 같이 캐싱과 에러 처리를 개선할 수 있습니다:
useEffect(() => { const sortProductsByReviewCount = async () => { if (!products || products.length === 0) return; const uniqueCategories = new Set(); products.forEach((item) => { if (item.recommendedCategory) uniqueCategories.add(item.recommendedCategory); if (item.defaultCategory) uniqueCategories.add(item.defaultCategory); }); const reviewCountMap = new Map(); + // 로컬 스토리지를 통한 간단한 캐싱 구현 + const cachedReviewCounts = localStorage.getItem('categoryReviewCounts'); + const cachedData = cachedReviewCounts ? JSON.parse(cachedReviewCounts) : {}; + const cacheTimestamp = localStorage.getItem('categoryReviewCountsTimestamp'); + const isCacheValid = cacheTimestamp && (Date.now() - parseInt(cacheTimestamp)) < 3600000; // 1시간 캐시 await Promise.all( [...uniqueCategories].map(async (korName) => { const enumKey = KOR_TO_ENUM_MAP[korName]; if (!enumKey) return; + // 유효한 캐시가 있으면 사용 + if (isCacheValid && cachedData[korName] !== undefined) { + reviewCountMap.set(korName, cachedData[korName]); + return; + } try { const res = await getConsumptionDetail(enumKey); reviewCountMap.set(korName, res?.reviewCount || 0); + // 캐시 업데이트 + cachedData[korName] = res?.reviewCount || 0; } catch (error) { + console.error(`카테고리 ${korName}의 리뷰 수를 가져오는 중 오류 발생:`, error); reviewCountMap.set(korName, 0); + // 캐시에 0 설정 + cachedData[korName] = 0; } }) ); + // 캐시 저장 + localStorage.setItem('categoryReviewCounts', JSON.stringify(cachedData)); + localStorage.setItem('categoryReviewCountsTimestamp', Date.now().toString()); const sorted = [...products].sort((a, b) => { const aCount = reviewCountMap.get(a.recommendedCategory) || reviewCountMap.get(a.defaultCategory) || 0; const bCount = reviewCountMap.get(b.recommendedCategory) || reviewCountMap.get(b.defaultCategory) || 0; return bCount - aCount; }); setSortedProducts(sorted); }; sortProductsByReviewCount(); }, [products]);
99-99: 🛠️ Refactor suggestion로딩 상태 처리 개선 필요
로딩 상태 확인 조건을 수정하여 isLoading이 true이거나 safeProducts가 비어 있을 때 스피너를 표시합니다. 그러나 이 조건은 실제로 상품이 없는 경우와 로딩 중인 경우를 구분하지 못합니다.
- {(isLoading || safeProducts.length === 0) && <Spinner />} + {isLoading ? ( + <Spinner /> + ) : ( + safeProducts.length === 0 && ( + <div className="w-full py-8 text-center text-gray-7"> + 표시할 금융 상품이 없습니다. + </div> + ) + )}
🧹 Nitpick comments (1)
src/pages/support/FinancialProductListPage.jsx (1)
15-26: 사용자 프로필 가져오기 로직 개선 필요프로필 정보를 가져오는 로직이 잘 구현되었지만, 로딩 상태를 표시하는 부분이 없습니다. 또한 사용자 경험을 위해 Suspense나 ErrorBoundary 등을 활용하여 좀 더 견고한 에러 처리를 구현하는 것이 좋겠습니다.
다음과 같이 로딩 상태를 추가하고 에러 처리를 개선할 수 있습니다:
const [userName, setUserName] = useState(""); + const [profileLoading, setProfileLoading] = useState(false); useEffect(() => { const fetchProfile = async () => { + setProfileLoading(true); try { const res = await getMyProfile(); setUserName(res?.name || "사용자"); } catch (e) { console.error("프로필 로딩 실패:", e); + // 사용자에게 에러를 표시하는 로직 추가 가능 } finally { + setProfileLoading(false); } }; fetchProfile(); }, []);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/pages/support/FinancialProductListPage.jsx(3 hunks)src/pages/support/components/ConsumerTab.jsx(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/pages/support/components/ConsumerTab.jsx
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/pages/support/FinancialProductListPage.jsx (2)
src/pages/support/constants/consumerMap.js (2)
KOR_TO_ENUM_MAP(27-34)KOR_TO_ENUM_MAP(27-34)src/components/common/Spinner.jsx (1)
Spinner(3-9)
🔇 Additional comments (4)
src/pages/support/FinancialProductListPage.jsx (4)
1-1: 필요한 API 및 유틸리티 추가가 잘 되었습니다.소비자 소비 유형 기반 추천 필터링을 위한 필수 기능들을 적절히 가져왔습니다.
Also applies to: 5-8
13-14: 상태 관리 로직이 잘 설계되었습니다.사용자 이름과 정렬된 상품 목록을 위한 상태 변수들이 명확하게 정의되었습니다.
Also applies to: 28-29
75-75: 방어적 프로그래밍이 잘 적용되었습니다.정렬된 상품이 항상 배열로 처리되도록 하는 안전장치가 적절히 구현되었습니다.
103-115: RecommendationCard 컴포넌트 props 전달이 잘 수정되었습니다.recommendedCategory와 defaultCategory props를 적절히 전달하여 카테고리 기반 필터링과 표시를 지원합니다.
| <div className="flex items-center justify-between mt-10"> | ||
| <p className="text-b5 font-medium text-gray-9"> | ||
| 총 {safeProducts.length}개 | ||
| </p> | ||
| <p className="text-caption2 text-primary-8 text-right"> | ||
| {userName}님이 리뷰를 남긴 기업 특성과 | ||
| <br /> 연관된 금융상품 순으로 보여드려요! | ||
| </p> |
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.
🛠️ Refactor suggestion
사용자 피드백 메시지 개선 필요
사용자 이름을 활용한 개인화된 메시지가 잘 구현되었습니다. 다만, "리뷰를 남긴 기업 특성과 연관된 금융상품 순으로 보여드려요"라는 문구가 사용자에게 명확하지 않을 수 있습니다. 특히 PR 코멘트에 언급된 바와 같이, 사용자들이 소셜 엔터프라이즈 유형 태그를 혼동할 수 있습니다.
다음과 같이 좀 더 명확한 메시지로 개선할 수 있습니다:
<p className="text-caption2 text-primary-8 text-right">
- {userName}님이 리뷰를 남긴 기업 특성과
- <br /> 연관된 금융상품 순으로 보여드려요!
+ {userName}님의 소비 패턴에 맞춰
+ <br /> 추천 금융상품을 보여드려요!
</p>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <div className="flex items-center justify-between mt-10"> | |
| <p className="text-b5 font-medium text-gray-9"> | |
| 총 {safeProducts.length}개 | |
| </p> | |
| <p className="text-caption2 text-primary-8 text-right"> | |
| {userName}님이 리뷰를 남긴 기업 특성과 | |
| <br /> 연관된 금융상품 순으로 보여드려요! | |
| </p> | |
| <div className="flex items-center justify-between mt-10"> | |
| <p className="text-b5 font-medium text-gray-9"> | |
| 총 {safeProducts.length}개 | |
| </p> | |
| <p className="text-caption2 text-primary-8 text-right"> | |
| {userName}님의 소비 패턴에 맞춰 | |
| <br /> 추천 금융상품을 보여드려요! | |
| </p> |
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
🔭 Outside diff range comments (1)
src/pages/map/components/PlaceContent.jsx (1)
170-172:⚠️ Potential issue잘못된 아이콘이 사용되고 있습니다.
전화번호를 표시하는데 위치 아이콘(
Ic_Location.svg)이 사용되고 있습니다. 전화번호에 맞는 아이콘으로 변경하는 것이 좋습니다.<img - src="/svgs/map/Ic_Location.svg" + src="/svgs/map/Ic_Phone.svg" alt="기업 전화번호" className="w-5 h-5" />
♻️ Duplicate comments (3)
src/pages/support/FinancialProductListPage.jsx (3)
28-73: 🛠️ Refactor suggestion상품 정렬 로직 개선 필요
소비 유형에 따른 상품 정렬 로직이 잘 구현되었습니다. 그러나 몇 가지 개선점이 있습니다:
- API 호출 실패 시 사용자 피드백이 없습니다
- 중복 API 호출을 최소화하기 위한 캐싱 메커니즘이 없습니다
- 각 카테고리별 API 호출이 많아질 경우 성능 이슈가 발생할 수 있습니다
const [sortedProducts, setSortedProducts] = useState([]); + const [isSorting, setIsSorting] = useState(false); useEffect(() => { const sortProductsByReviewCount = async () => { if (!products || products.length === 0) return; + setIsSorting(true); const uniqueCategories = new Set(); products.forEach((item) => { if (item.recommendedCategory) uniqueCategories.add(item.recommendedCategory); if (item.defaultCategory) uniqueCategories.add(item.defaultCategory); }); const reviewCountMap = new Map(); + // 로컬 스토리지를 통한 간단한 캐싱 구현 + const cachedReviewCounts = localStorage.getItem('categoryReviewCounts'); + const cachedData = cachedReviewCounts ? JSON.parse(cachedReviewCounts) : {}; + const cacheTimestamp = localStorage.getItem('categoryReviewCountsTimestamp'); + const isCacheValid = cacheTimestamp && (Date.now() - parseInt(cacheTimestamp)) < 3600000; // 1시간 캐시 await Promise.all( [...uniqueCategories].map(async (korName) => { const enumKey = KOR_TO_ENUM_MAP[korName]; if (!enumKey) return; + // 유효한 캐시가 있으면 사용 + if (isCacheValid && cachedData[korName] !== undefined) { + reviewCountMap.set(korName, cachedData[korName]); + return; + } try { const res = await getConsumptionDetail(enumKey); reviewCountMap.set(korName, res?.reviewCount || 0); + // 캐시 업데이트 + cachedData[korName] = res?.reviewCount || 0; } catch (error) { + console.error(`카테고리 ${korName}의 리뷰 수를 가져오는 중 오류 발생:`, error); reviewCountMap.set(korName, 0); + // 캐시에 0 설정 + cachedData[korName] = 0; } }) ); + // 캐시 저장 + localStorage.setItem('categoryReviewCounts', JSON.stringify(cachedData)); + localStorage.setItem('categoryReviewCountsTimestamp', Date.now().toString()); const sorted = [...products].sort((a, b) => { const aCount = reviewCountMap.get(a.recommendedCategory) || reviewCountMap.get(a.defaultCategory) || 0; const bCount = reviewCountMap.get(b.recommendedCategory) || reviewCountMap.get(b.defaultCategory) || 0; return bCount - aCount; }); setSortedProducts(sorted); + setIsSorting(false); }; sortProductsByReviewCount(); }, [products]);
89-96: 🛠️ Refactor suggestion사용자 피드백 메시지 개선 필요
사용자 이름을 활용한 개인화된 메시지가 잘 구현되었습니다. 다만, "리뷰를 남긴 기업 특성과 연관된 금융상품 순으로 보여드려요"라는 문구가 사용자에게 명확하지 않을 수 있습니다. 특히 PR 코멘트에 언급된 바와 같이, 사용자들이 소셜 엔터프라이즈 유형 태그를 혼동할 수 있습니다.
<p className="caption2 text-primary-8 text-right"> - {userName}님이 리뷰를 남긴 기업 특성과 - <br /> 연관된 금융상품 순으로 보여드려요! + {userName}님의 소비 패턴에 맞춰 + <br /> 추천 금융상품을 보여드려요! </p>
99-99: 🛠️ Refactor suggestion로딩 상태 처리 개선
로딩 상태 확인 조건을 수정하여 isLoading이 true이거나 safeProducts가 비어 있을 때 스피너를 표시합니다. 그러나 이 조건은 실제로 상품이 없는 경우와 로딩 중인 경우를 구분하지 못합니다.
- {(isLoading || safeProducts.length === 0) && <Spinner />} + {isLoading ? ( + <Spinner /> + ) : ( + safeProducts.length === 0 && ( + <div className="w-full py-8 text-center text-gray-7"> + 표시할 금융 상품이 없습니다. + </div> + ) + )}
🧹 Nitpick comments (1)
src/pages/support/FinancialProductListPage.jsx (1)
13-26: 사용자 프로필 로딩 로직이 잘 구현되었습니다.사용자 이름을 가져오는 로직이 적절하게 구현되어 있으며, 오류 처리와 기본값 설정도 잘 되어 있습니다. 다만, 프로필 로딩 중에 사용자에게 보여줄 로딩 상태 표시가 없어 UX를 개선할 여지가 있습니다.
const [userName, setUserName] = useState(""); + const [isProfileLoading, setIsProfileLoading] = useState(false); useEffect(() => { const fetchProfile = async () => { + setIsProfileLoading(true); try { const res = await getMyProfile(); setUserName(res?.name || "사용자"); } catch (e) { console.error("프로필 로딩 실패:", e); } finally { + setIsProfileLoading(false); } }; fetchProfile(); }, []);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (19)
src/pages/join/components/GoHome.jsx(2 hunks)src/pages/join/components/LocationStep.jsx(6 hunks)src/pages/join/components/NameStep.jsx(2 hunks)src/pages/join/components/OwnerStep.jsx(1 hunks)src/pages/join/components/ProfileImageStep.jsx(1 hunks)src/pages/kakaoAuth/kakaoAuth.jsx(1 hunks)src/pages/map/MapPage.jsx(1 hunks)src/pages/map/components/CategoryBar.jsx(1 hunks)src/pages/map/components/IntroModal.jsx(2 hunks)src/pages/map/components/PlaceContent.jsx(5 hunks)src/pages/search/SearchPage.jsx(1 hunks)src/pages/search/components/PlaceCard.jsx(2 hunks)src/pages/search/components/SearchPlaceList.jsx(1 hunks)src/pages/story/components/carousel/StoryCarousel.jsx(1 hunks)src/pages/support/FinancialProductDetailPage.jsx(3 hunks)src/pages/support/FinancialProductListPage.jsx(3 hunks)src/pages/support/components/ConsumerTab.jsx(4 hunks)src/pages/support/components/ConsumptionChart.jsx(6 hunks)src/pages/support/components/RecommendationCard.jsx(3 hunks)
✅ Files skipped from review due to trivial changes (13)
- src/pages/kakaoAuth/kakaoAuth.jsx
- src/pages/map/MapPage.jsx
- src/pages/map/components/IntroModal.jsx
- src/pages/join/components/OwnerStep.jsx
- src/pages/search/components/SearchPlaceList.jsx
- src/pages/map/components/CategoryBar.jsx
- src/pages/search/SearchPage.jsx
- src/pages/join/components/GoHome.jsx
- src/pages/join/components/LocationStep.jsx
- src/pages/search/components/PlaceCard.jsx
- src/pages/join/components/ProfileImageStep.jsx
- src/pages/join/components/NameStep.jsx
- src/pages/story/components/carousel/StoryCarousel.jsx
🚧 Files skipped from review as they are similar to previous changes (4)
- src/pages/support/components/ConsumptionChart.jsx
- src/pages/support/FinancialProductDetailPage.jsx
- src/pages/support/components/RecommendationCard.jsx
- src/pages/support/components/ConsumerTab.jsx
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/pages/map/components/PlaceContent.jsx (1)
src/constants/categoryMap.js (2)
businessTypeNameMap(32-43)businessTypeNameMap(32-43)
🔇 Additional comments (7)
src/pages/support/FinancialProductListPage.jsx (2)
5-8: 새로운 의존성 추가 부분이 적절히 구현되었습니다.API 및 상수 관련 임포트가 명확하게 추가되었습니다. 금융 상품 데이터와 사용자 프로필을 가져오는 API 함수들이 적절히 임포트되었습니다.
103-115: 카테고리 정보가 올바르게 전달되고 있습니다.금융 상품 카드에 recommendedCategory와 defaultCategory 정보를 적절히 전달하고 있습니다. 이로써 상품 카드에서 적절한 카테고리 정보를 표시할 수 있게 되었습니다.
src/pages/map/components/PlaceContent.jsx (5)
82-90: 클래스 이름 변경이 적절하게 적용되었습니다.스타일 리팩토링에 맞게 타이포그래피 클래스 이름이 간결하게 변경되었습니다.
b4클래스가 기존 font-weight 설정을 포함하고 있는지 확인하세요.
96-98: 클래스 이름 변경이 적절하게 적용되었습니다.비즈니스 설명을 위한 컨테이너의 스타일링이 코드베이스의 전반적인 타이포그래피 리팩토링 방향에 맞게 업데이트되었습니다.
106-108: 클래스 이름 변경이 적절하게 적용되었습니다.
text-caption2대신caption2로 변경한 것이 전체 코드베이스의 타이포그래피 클래스 단순화 패턴과 일치합니다.
148-165: 클래스 이름 변경이 적절하게 적용되었습니다.위치 정보 컨테이너의 클래스 이름이 새로운 타이포그래피 시스템에 맞게 적절히 업데이트되었습니다.
168-185: 클래스 이름 변경이 적절하게 적용되었습니다.전화번호 정보 컨테이너의 클래스 이름이 새로운 타이포그래피 시스템에 맞게 적절히 업데이트되었습니다.
| <h3 className="h3 break-words text-gray-12"> | ||
| <div className="max-w-full h3 text-gray-12 break-keep whitespace-normal mt-6"> | ||
| {companyName} | ||
| <span className="ml-2 text-b5 text-gray-6 font-medium"> | ||
| <span className="ml-2 b5 text-gray-6"> | ||
| {businessTypeNameMap[companyCategory] ?? companyCategory} | ||
| </span> | ||
| </div> | ||
| </h3> |
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.
HTML 구조에 중복되는 h3 및 div 태그가 있습니다.
h3 태그 안에 동일한 h3 클래스를 가진 div를 중첩시킨 것은 HTML 구조상 문제가 될 수 있습니다. 이러한 중첩은 스타일 충돌이나 예기치 않은 렌더링 결과를 초래할 수 있습니다.
아래와 같이 구조를 수정하는 것이 좋습니다:
- <h3 className="h3 break-words text-gray-12">
- <div className="max-w-full h3 text-gray-12 break-keep whitespace-normal mt-6">
+ <h3 className="max-w-full h3 text-gray-12 break-keep whitespace-normal mt-6">
{companyName}
<span className="ml-2 b5 text-gray-6">
{businessTypeNameMap[companyCategory] ?? companyCategory}
</span>
- </div>
</h3>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <h3 className="h3 break-words text-gray-12"> | |
| <div className="max-w-full h3 text-gray-12 break-keep whitespace-normal mt-6"> | |
| {companyName} | |
| <span className="ml-2 text-b5 text-gray-6 font-medium"> | |
| <span className="ml-2 b5 text-gray-6"> | |
| {businessTypeNameMap[companyCategory] ?? companyCategory} | |
| </span> | |
| </div> | |
| </h3> | |
| <h3 className="max-w-full h3 text-gray-12 break-keep whitespace-normal mt-6"> | |
| {companyName} | |
| <span className="ml-2 b5 text-gray-6"> | |
| {businessTypeNameMap[companyCategory] ?? companyCategory} | |
| </span> | |
| </h3> |


🌟 어떤 이유로 MR를 하셨나요?
📝 세부 내용 - 왜 해당 MR이 필요한지 작업 내용을 자세하게 설명해주세요
📸 작업 화면 스크린샷
2025-05-09.5.06.05.mov
📢 로컬 실행 시 유의사항
🚨 관련 이슈 번호
Summary by CodeRabbit
신규 기능
기능 개선
버그 수정/스타일
기타