[251209] feat: ShopByShow-8

🕐 커밋 시간: 2025. 12. 09. 17:49:58

📊 변경 통계:
  • 총 파일: 5개
  • 추가: +69줄
  • 삭제: -22줄

📝 수정된 파일:
  ~ com.twin.app.shoptime/src/views/FeaturedBrandsPanel/FeaturedBrandsPanel.jsx
  ~ com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShow.jsx
  ~ com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowContents/ShopByShowContents.jsx
  ~ com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowContents/ShopByShowProductList/ShopByShowProductList.jsx
  ~ com.twin.app.shoptime/src/views/FeaturedBrandsPanel/ShopByShow/ShopByShowList/ShopByShowNav/ShopByShowNav.jsx

🔧 주요 변경 내용:
  • 소규모 기능 개선
This commit is contained in:
2025-12-09 17:49:58 +09:00
parent 407b4c7751
commit aa1f9630e6
5 changed files with 69 additions and 22 deletions

View File

@@ -773,15 +773,20 @@ const FeaturedBrandsPanel = ({ isOnTop, panelInfo, spotlightId }) => {
// effect: set selectedPatnrId and selectedPatncNm
useEffect(() => {
if (brandInfo) {
const patnrId = panelInfo?.patnrId;
const patncNm = brandInfo.find((b) => b?.patnrId === patnrId).patncNm;
if (brandInfo && panelInfo?.patnrId) {
const patnrId = panelInfo.patnrId;
const patncNm = brandInfo.find((b) => b?.patnrId === patnrId)?.patncNm;
setSelectedPatncNm(patncNm);
if (patncNm) {
setSelectedPatncNm(patncNm);
}
if (!fromDetail) setSelectedPatnrId(patnrId);
// Detail에서 돌아와도 patnrId가 비어 있으면 다시 설정해 API 호출이 정상 동작하도록 보완
if (!fromDetail || !selectedPatnrId) {
setSelectedPatnrId(patnrId);
}
}
}, [brandInfo, panelInfo?.patnrId]);
}, [brandInfo, panelInfo?.patnrId, selectedPatnrId, fromDetail]);
// effect: data fetching based on brandLayoutInfo and selectedPatnrId
useEffect(() => {
@@ -791,6 +796,16 @@ const FeaturedBrandsPanel = ({ isOnTop, panelInfo, spotlightId }) => {
Object.entries(DISPATCH_MAP) //
.forEach(([templateCode, action]) => {
if (hasTemplateCodeWithValue(sortedBrandLayoutInfo, templateCode)) {
// Detail 복귀 시 ShopByShow 데이터가 이미 있으면 재호출을 건너뛰어 선택 상태가 초기화되는 것을 방지
if (
templateCode === TEMPLATE_CODE_CONF.NBCU &&
fromDetail &&
shouldRenderComponent(brandShopByShowContsList)
) {
console.log("[FeaturedBrandsPanel] Skip re-fetch ShopByShow on return from detail");
return;
}
console.log("[FeaturedBrandsPanel] Fetching data for template:", templateCode, "patnrId:", selectedPatnrId);
dispatch(action({ patnrId: selectedPatnrId }));
}

View File

@@ -11,9 +11,11 @@ import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDeco
import useScrollTo from "../../../hooks/useScrollTo";
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
import { $L } from "../../../utils/helperMethods";
import { panel_names } from "../../../utils/Config";
import css from "./ShopByShow.module.less";
import ShopByShowNav from "./ShopByShowList/ShopByShowNav/ShopByShowNav";
import ShopByShowContents from "./ShopByShowList/ShopByShowContents/ShopByShowContents";
import { updatePanel } from "../../../actions/panelActions";
const STRING_CONF = {
SHOP_BY_SHOW: "SHOP BY SHOW",
@@ -43,16 +45,40 @@ const ShopByShow = ({
const brandShopByShowClctInfos = brandShopByShowContsInfo?.brandShopByShowClctInfos || [];
const handleContsIdChange = useCallback((contsId) => {
setSelectedContsId(contsId);
// 'ALL' 버튼 클릭 시 (contsId === null) 첫 번째 contents 로드
const targetContsId = contsId || (brandShopByShowContsList?.[0]?.contsId);
if (targetContsId) {
dispatch(getBrandShopByShow({ patnrId: selectedPatnrId, contsId: targetContsId }));
// DetailPanel 복귀 시 panelInfo에 저장된 contsId로 네비게이션 선택을 복구
useEffect(() => {
if (panelInfo?.contsId && panelInfo.contsId !== selectedContsId) {
setSelectedContsId(panelInfo.contsId);
}
}, [selectedPatnrId, brandShopByShowContsList, dispatch]);
}, [panelInfo?.contsId, selectedContsId]);
const handleContsIdChange = useCallback(
(contsId) => {
// patnrId가 없으면 Detail 복귀 직후라 정상 호출 불가
if (!selectedPatnrId) return;
setSelectedContsId(contsId);
// 현재 선택된 contsId를 패널 상태에 저장해 복귀 시 복원
dispatch(
updatePanel({
name: panel_names.FEATURED_BRANDS_PANEL,
panelInfo: {
...(panelInfo || {}),
contsId,
},
})
);
// 'ALL' 버튼 클릭 시 (contsId === null) 첫 번째 contents 로드
const targetContsId = contsId || brandShopByShowContsList?.[0]?.contsId;
if (targetContsId) {
dispatch(getBrandShopByShow({ patnrId: selectedPatnrId, contsId: targetContsId }));
}
},
[selectedPatnrId, brandShopByShowContsList, dispatch]
);
useEffect(() => {
if (panelInfo?.section !== "shop-by-show" || !panelInfo?.x) {
@@ -127,6 +153,7 @@ const ShopByShow = ({
handleItemFocus={_handleItemFocus}
clctNm={collection.clctNm}
clctImgUrl={collection.clctImgUrl}
contsId={brandShopByShowContsInfo?.contsId || selectedContsId}
patnrId={selectedPatnrId}
selectedPatnrId={selectedPatnrId}
shelfOrder={shelfOrder}

View File

@@ -17,6 +17,7 @@ export default memo(function ShopByShowContents({
handleItemFocus,
clctNm,
clctImgUrl,
contsId,
patnrId,
selectedPatnrId,
shelfOrder,
@@ -50,6 +51,7 @@ export default memo(function ShopByShowContents({
brandProductInfos={brandProductInfos}
contentsIndex={contentsIndex}
handleFocus={handleFocus}
contsId={contsId}
patnrId={patnrId}
selectedPatnrId={selectedPatnrId}
clctNm={clctNm}

View File

@@ -23,6 +23,7 @@ export default function ShopByShowProductList({
brandProductInfos,
contentsIndex,
handleFocus,
contsId,
patnrId,
selectedPatnrId,
clctNm,
@@ -85,6 +86,7 @@ export default function ShopByShowProductList({
lastFocusedTargetId,
patnrId: effectivePatnrId,
section,
contsId,
x,
},
})
@@ -94,11 +96,11 @@ export default function ShopByShowProductList({
dispatch(
pushPanel({
name: panel_names.DETAIL_PANEL,
panelInfo: { patnrId: effectivePatnrId, prdtId },
panelInfo: { patnrId: effectivePatnrId, prdtId, contsId },
})
);
},
[dispatch, patnrId]
[dispatch, patnrId, contsId]
);
const renderItem = useCallback(

View File

@@ -25,6 +25,7 @@ export default memo(function ShopByShowNav({
selectedContsId,
}) {
const { getScrollTo, scrollLeft } = useScrollTo();
const activeContsId = selectedContsId ?? brandShopByShowContsInfo?.contsId;
const handleClick = useCallback(
(contsId) => () => {
@@ -39,7 +40,7 @@ export default memo(function ShopByShowNav({
}
}, [handleItemFocus]);
const selectedText = !selectedContsId ? "Selected " : "";
const selectedText = !activeContsId ? "Selected " : "";
const allLabeltext = selectedText + "ALL 1 of " + (brandShopByShowContsList.length + 1);
return (
@@ -62,14 +63,14 @@ export default memo(function ShopByShowNav({
{brandShopByShowContsList &&
brandShopByShowContsList.map(({ contsId, contsNm }, index) => (
<li key={"shop-by-show-conts-" + index}>
<TButton
className={brandShopByShowContsInfo?.contsId === contsId && css.selected}
<TButton
className={activeContsId === contsId && css.selected}
onClick={handleClick(contsId)}
onFocus={handleFocus}
selected={brandShopByShowContsInfo?.contsId === contsId}
selected={activeContsId === contsId}
type={TYPES.oneDepthCategory}
ariaLabel={
brandShopByShowContsInfo?.contsId === contsId
activeContsId === contsId
? "Selected " + contsNm + " " + (index * 1 + 1) + " of " + brandShopByShowContsList.length
: "" + contsNm + " " + (index * 1 + 1) + " of " + brandShopByShowContsList.length
}