[251126] feat: Featured Brands - NBCU Page Rendering using BestSeller

🕐 커밋 시간: 2025. 11. 26. 20:56:09

📊 변경 통계:
  • 총 파일: 7개
  • 추가: +145줄
  • 삭제: -64줄

📁 추가된 파일:
  + com.twin.app.shoptime/assets/images/featuredBrands/image-bg.png

📝 수정된 파일:
  ~ com.twin.app.shoptime/src/views/FeaturedBrandsPanel/Banner/Banner.jsx
  ~ com.twin.app.shoptime/src/views/FeaturedBrandsPanel/FeaturedBrandsPanel.jsx
  ~ com.twin.app.shoptime/src/views/FeaturedBrandsPanel/NBCUContent/NBCUContent.jsx
  ~ com.twin.app.shoptime/src/views/FeaturedBrandsPanel/NBCUContent/NBCUContent.module.less
  ~ com.twin.app.shoptime/src/views/FeaturedBrandsPanel/NBCUContent/NBCUList/NBCUList.jsx
  ~ com.twin.app.shoptime/src/views/FeaturedBrandsPanel/QuickMenu/QuickMenu.jsx

🔧 주요 변경 내용:
  • 중간 규모 기능 개선
  • 모듈 구조 개선
This commit is contained in:
2025-11-26 20:56:10 +09:00
parent 57cc6dbf20
commit a5fbb21d43
7 changed files with 145 additions and 64 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View File

@@ -1,6 +1,7 @@
import React, { memo } from "react";
import IcPartnersDefault from "../../../../assets/images/ic-tab-partners-default@3x.png";
import NBCULogoImage from "../../../../assets/images/featuredBrands/image-nbcu.png";
import CustomImage from "../../../components/CustomImage/CustomImage";
import css from "./Banner.module.less";
@@ -15,16 +16,20 @@ export default memo(function Banner({
const { patncLogoPath, patncNm } = selectedBrandInfo;
const { topImgAlt, topImgPath } = brandTopImgInfo;
// NBCU 로고 이미지 처리
const logoSrc = panelPatnrId === 'NBCU' ? NBCULogoImage : patncLogoPath;
const logoName = panelPatnrId === 'NBCU' ? 'Peacock' : patncNm;
return (
<div className={css.container}>
<figure>
<CustomImage
src={patncLogoPath}
alt={patncNm}
src={logoSrc}
alt={logoName}
fallbackSrc={IcPartnersDefault}
ariaLabel={patncNm}
ariaLabel={logoName}
/>
<figcaption>{patncNm}</figcaption>
<figcaption>{logoName}</figcaption>
</figure>
<CustomImage src={topImgPath} alt={topImgAlt} ariaLabel={topImgAlt} />
</div>

View File

@@ -69,6 +69,7 @@ import TodaysDeals from "./TodaysDeals/TodaysDeals";
import UpComing from "./UpComing/UpComing";
import { setContainerLastFocusedElement } from "@enact/spotlight/src/container";
import { sortedIndexOf } from "lodash";
import NBCUBgImage from "../../../assets/images/featuredBrands/image-bg.png";
const STRING_CONF = {
CANCEL: "CANCEL",
@@ -326,6 +327,24 @@ const FeaturedBrandsPanel = ({ isOnTop, panelInfo, spotlightId }) => {
[brandLayoutInfo, panelInfo?.patnrId]
);
const processedBrandTopImgInfo = useMemo(
() => {
// NBCU 특별 처리
if (panelInfo?.patnrId === 'NBCU') {
return {
topImgPath: NBCUBgImage,
topImgAlt: 'NBCU Background Image',
};
}
// 다른 브랜드: brandTopImgInfo가 유효한 객체여야 함
if (brandTopImgInfo && brandTopImgInfo.topImgPath) {
return brandTopImgInfo;
}
return null;
},
[brandTopImgInfo, panelInfo?.patnrId]
);
const doSendLogGNB = useCallback(
(containerId, shelfOrder) => {
if (
@@ -440,6 +459,9 @@ const FeaturedBrandsPanel = ({ isOnTop, panelInfo, spotlightId }) => {
handleItemFocus={handleItemFocus}
spotlightId={TEMPLATE_CODE_CONF.NBCU}
shelfOrder={el.expsOrd}
shelfTitle={el.shptmBrndOptTpNm}
selectedPatnrId={selectedPatnrId}
order={idx + 1}
/>
</React.Fragment>
);
@@ -995,10 +1017,10 @@ const FeaturedBrandsPanel = ({ isOnTop, panelInfo, spotlightId }) => {
/>
)}
{brandInfo && brandTopImgInfo && (
{((brandInfo && processedBrandTopImgInfo) || panelInfo?.patnrId === 'NBCU') && processedBrandTopImgInfo && (
<Banner
brandInfo={brandInfo}
brandTopImgInfo={brandTopImgInfo}
brandTopImgInfo={processedBrandTopImgInfo}
panelPatnrId={panelInfo?.patnrId}
/>
)}

View File

@@ -1,14 +1,78 @@
import React, { memo } from 'react';
import css from './NBCUContent.module.less';
import React, { memo, useCallback, useState } from "react";
import Spotlight from "@enact/spotlight";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
import { $L } from "../../../utils/helperMethods";
import css from "./NBCUContent.module.less";
import NBCUList from "./NBCUList/NBCUList";
const STRING_CONF = {
NBCU: "NBCU",
};
const Container = SpotlightContainerDecorator(
{ leaveFor: { right: "" }, enterTo: "last-focused" },
"div"
);
const NBCUContent = ({
handleItemFocus,
spotlightId,
shelfOrder,
selectedPatnrId,
shelfTitle,
order,
}) => {
const [firstChk, setFirstChk] = useState(0);
const _handleItemFocus = useCallback(() => {
if (handleItemFocus) handleItemFocus(spotlightId, shelfOrder);
const c = Spotlight.getCurrent();
if (firstChk === 0) {
if (c) {
let cAriaLabel = c.getAttribute("aria-label");
if (cAriaLabel) {
cAriaLabel = "NBCU, Heading1," + cAriaLabel;
c.setAttribute("aria-label", cAriaLabel);
}
}
setFirstChk(1);
} else if (firstChk === 1) {
if (c) {
let cAriaLabel = c.getAttribute("aria-label");
if (cAriaLabel) {
const newcAriaLabel = cAriaLabel.replace("NBCU, Heading1,", "");
c.setAttribute("aria-label", newcAriaLabel);
}
}
} else {
return;
}
}, [handleItemFocus, firstChk, spotlightId, shelfOrder]);
const NBCUContent = ({ handleItemFocus, spotlightId, shelfOrder = 1 }) => {
return (
<div className={css.container} data-wheel-point>
<div className={css.content}>
<h2 className={css.title}>NBCU</h2>
<p className={css.message}>Content Coming Soon</p>
</div>
</div>
<Container
className={css.container}
data-shelf-order={order}
data-wheel-point
spotlightId={spotlightId}
>
<SectionTitle
title={$L(STRING_CONF.NBCU)}
data-title="nbcu"
label="NBCU Heading 1"
/>
<NBCUList
handleItemFocus={_handleItemFocus}
spotlightId={spotlightId}
shelfOrder={shelfOrder}
shelfTitle={shelfTitle}
selectedPatnrId={selectedPatnrId}
/>
</Container>
);
};

View File

@@ -1,28 +1 @@
@import "../../../style/CommonStyle.module.less";
.container {
width: 100%;
padding: 40px 60px;
margin-bottom: 58px;
}
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 400px;
}
.title {
font-size: 32px;
font-weight: bold;
margin-bottom: 20px;
color: #333;
}
.message {
font-size: 18px;
color: #666;
margin: 0;
}

View File

@@ -49,7 +49,7 @@ const NBCUList = ({ handleItemFocus, spotlightId, shelfTitle, shelfOrder }) => {
);
return (
<Container className={css.container} spotlightId={spotlightId}>
<Container className={css.container} spotlightId="nbcu-list-id">
<TVirtualGridList
dataSize={DUMMY_DATA.length}
direction="horizontal"

View File

@@ -77,6 +77,8 @@ const QuickMenu = ({
noScrollByWheel
>
<ul ref={ulRef}>
{panelPatnrId === 'NBCU' ? (
<>
<QuickMenuItemNBCU
itemIndex={0}
handleItemFocus={_handleItemFocus}
@@ -98,6 +100,21 @@ const QuickMenu = ({
label={(itemIndex + 2) + " of " + (brandInfo.length + 1)}
/>
))}
</>
) : (
brandInfo.map((brandInfoItem, itemIndex) => (
<QuickMenuItem
brandInfoItem={brandInfoItem}
itemIndex={itemIndex}
handleItemFocus={_handleItemFocus}
key={"brand-info" + itemIndex}
resetStates={resetStates}
scrollLeft={scrollLeft}
selectedPatnrId={selectedPatnrId}
label={(itemIndex + 1) + " of " + brandInfo.length}
/>
))
)}
</ul>
</TScroller>
</Container>