Compare commits
6 Commits
backup-202
...
cdf0d3de04
| Author | SHA1 | Date | |
|---|---|---|---|
| cdf0d3de04 | |||
| 9ff6064bc9 | |||
| cfee554bf6 | |||
| a5fbb21d43 | |||
| 57cc6dbf20 | |||
| 74d2b827b0 |
2
com.twin.app.shoptime/.gitignore
vendored
2
com.twin.app.shoptime/.gitignore
vendored
@@ -22,3 +22,5 @@ nul
|
||||
OPTIMAL.md
|
||||
.docs
|
||||
|
||||
GEMINI.md
|
||||
|
||||
|
||||
BIN
com.twin.app.shoptime/assets/images/featuredBrands/image-bg.png
Normal file
BIN
com.twin.app.shoptime/assets/images/featuredBrands/image-bg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 346 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 186 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 256 KiB |
@@ -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>
|
||||
|
||||
@@ -60,6 +60,7 @@ import css from "./FeaturedBrandsPanel.module.less";
|
||||
import FeaturedCategory from "./FeaturedCategory/FeaturedCategory";
|
||||
import FeaturedCreators from "./FeaturedCreators/FeaturedCreators";
|
||||
import LiveChannels from "./LiveChannels/LiveChannels";
|
||||
import NBCUContent from "./NBCUContent/NBCUContent";
|
||||
import QuickMenu from "./QuickMenu/QuickMenu";
|
||||
import RecommendedShows from "./RecommendedShows/RecommendedShows";
|
||||
import Series from "./Series/Series";
|
||||
@@ -68,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",
|
||||
@@ -81,6 +83,7 @@ const STRING_CONF = {
|
||||
};
|
||||
|
||||
const TEMPLATE_CODE_CONF = {
|
||||
NBCU: "NBU00100",
|
||||
LIVE_CHANNELS: "BRD00101",
|
||||
UP_COMING: "BRD00102",
|
||||
TODAYS_DEALS: "BRD00103",
|
||||
@@ -304,8 +307,42 @@ const FeaturedBrandsPanel = ({ isOnTop, panelInfo, spotlightId }) => {
|
||||
);
|
||||
|
||||
const sortedBrandLayoutInfo = useMemo(
|
||||
() => brandLayoutInfo?.sort((a, b) => a.expsOrd - b.expsOrd) ?? [],
|
||||
[brandLayoutInfo]
|
||||
() => {
|
||||
if (!panelInfo?.patnrId) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// NBCU 특별 처리
|
||||
if (panelInfo?.patnrId === 'NBCU') {
|
||||
return [
|
||||
{
|
||||
shptmBrndOptTpCd: TEMPLATE_CODE_CONF.NBCU,
|
||||
shptmBrndOptTpNm: 'NBCU',
|
||||
expsOrd: 1,
|
||||
},
|
||||
];
|
||||
}
|
||||
return brandLayoutInfo?.sort((a, b) => a.expsOrd - b.expsOrd) ?? [];
|
||||
},
|
||||
[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(
|
||||
@@ -415,6 +452,21 @@ const FeaturedBrandsPanel = ({ isOnTop, panelInfo, spotlightId }) => {
|
||||
<>
|
||||
{sortedBrandLayoutInfo.map((el, idx) => {
|
||||
switch (el.shptmBrndOptTpCd) {
|
||||
case TEMPLATE_CODE_CONF.NBCU: {
|
||||
return (
|
||||
<React.Fragment key={el.shptmBrndOptTpCd}>
|
||||
<NBCUContent
|
||||
handleItemFocus={handleItemFocus}
|
||||
spotlightId={TEMPLATE_CODE_CONF.NBCU}
|
||||
shelfOrder={el.expsOrd}
|
||||
shelfTitle={el.shptmBrndOptTpNm}
|
||||
selectedPatnrId={selectedPatnrId}
|
||||
order={idx + 1}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
case TEMPLATE_CODE_CONF.LIVE_CHANNELS: {
|
||||
return (
|
||||
<React.Fragment key={el.shptmBrndOptTpCd}>
|
||||
@@ -709,7 +761,7 @@ const FeaturedBrandsPanel = ({ isOnTop, panelInfo, spotlightId }) => {
|
||||
|
||||
// effect: layout information fetching due to partner id change
|
||||
useEffect(() => {
|
||||
if (!fromDetail) {
|
||||
if (!fromDetail && panelInfo?.patnrId) {
|
||||
dispatch({ type: types.RESET_BRAND_LAYOUT_INFO });
|
||||
dispatch(getBrandLayoutInfo({ patnrId: panelInfo?.patnrId }));
|
||||
setIsInitialFocusOccurred(false);
|
||||
@@ -719,14 +771,21 @@ const FeaturedBrandsPanel = ({ isOnTop, panelInfo, spotlightId }) => {
|
||||
|
||||
// effect: set selectedPatnrId and selectedPatncNm
|
||||
useEffect(() => {
|
||||
if (brandInfo) {
|
||||
if (brandInfo || panelInfo?.patnrId) {
|
||||
const patnrId = panelInfo?.patnrId;
|
||||
const patncNm = brandInfo.find((b) => b?.patnrId === patnrId).patncNm;
|
||||
|
||||
setSelectedPatncNm(patncNm);
|
||||
|
||||
// NBCU 특별 처리
|
||||
if (patnrId === 'NBCU') {
|
||||
setSelectedPatncNm('NBCU');
|
||||
if (!fromDetail) setSelectedPatnrId('NBCU');
|
||||
} else if (brandInfo) {
|
||||
const brandItem = brandInfo.find((b) => b?.patnrId === patnrId);
|
||||
if (brandItem) {
|
||||
setSelectedPatncNm(brandItem.patncNm);
|
||||
if (!fromDetail) setSelectedPatnrId(patnrId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [brandInfo, panelInfo?.patnrId]);
|
||||
|
||||
// effect: data fetching based on brandLayoutInfo and selectedPatnrId
|
||||
@@ -958,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}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
import React, { memo, useCallback, useState, useEffect } from "react";
|
||||
|
||||
import Spotlight from "@enact/spotlight";
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
import Spottable from "@enact/spotlight/Spottable";
|
||||
|
||||
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
|
||||
import NBCUSectionTitle from "./NBCUSectionTitle/NBCUSectionTitle";
|
||||
import { $L } from "../../../utils/helperMethods";
|
||||
import css from "./NBCUContent.module.less";
|
||||
import NBCUList from "./NBCUList/NBCUList";
|
||||
import NBCUSeries from "./NBCUSeries/NBCUSeries";
|
||||
import seriesCard1 from "../../../../assets/images/featuredBrands/series-card-1.png";
|
||||
import seriesCard2 from "../../../../assets/images/featuredBrands/series-card-2.png";
|
||||
import seriesCard3 from "../../../../assets/images/featuredBrands/series-card-3.png";
|
||||
|
||||
const STRING_CONF = {
|
||||
NBCU: "NBCU",
|
||||
PICKED_FOR_YOU: "PICKED FOR YOU",
|
||||
};
|
||||
|
||||
// Mock data for Series
|
||||
const MOCK_BRAND_SERIES_GROUP_INFO = [
|
||||
{
|
||||
seriesId: "series-1",
|
||||
seriesNm: "Drama Collection",
|
||||
seriesImgUrl: seriesCard1,
|
||||
patnrId: "nbcu-partner-1",
|
||||
brandSeriesProductInfo: Array.from({ length: 6 }).map((_, i) => ({
|
||||
productId: `drama-${i}`,
|
||||
productNm: `Drama Show ${i + 1}`,
|
||||
imageUrl: "assets/images/img-thumb-empty-product@3x.png",
|
||||
priceInfo: "$15.00|$10.00|N|$5.00|33%|PROMO|2025-12-31",
|
||||
})),
|
||||
},
|
||||
{
|
||||
seriesId: "series-2",
|
||||
seriesNm: "Comedy Series",
|
||||
seriesImgUrl: seriesCard2,
|
||||
patnrId: "nbcu-partner-1",
|
||||
brandSeriesProductInfo: Array.from({ length: 6 }).map((_, i) => ({
|
||||
productId: `comedy-${i}`,
|
||||
productNm: `Comedy Show ${i + 1}`,
|
||||
imageUrl: "assets/images/img-thumb-empty-product@3x.png",
|
||||
priceInfo: "$12.00|$8.00|N|$4.00|33%|PROMO|2025-12-31",
|
||||
})),
|
||||
},
|
||||
{
|
||||
seriesId: "series-3",
|
||||
seriesNm: "Sci-Fi Originals",
|
||||
seriesImgUrl: seriesCard3,
|
||||
patnrId: "nbcu-partner-1",
|
||||
brandSeriesProductInfo: Array.from({ length: 6 }).map((_, i) => ({
|
||||
productId: `scifi-${i}`,
|
||||
productNm: `Sci-Fi Show ${i + 1}`,
|
||||
imageUrl: "assets/images/img-thumb-empty-product@3x.png",
|
||||
priceInfo: "$18.00|$12.00|N|$6.00|33%|PROMO|2025-12-31",
|
||||
})),
|
||||
},
|
||||
];
|
||||
|
||||
const MOCK_BRAND_SERIES_INFO = [
|
||||
{ seriesId: "series-1", seriesNm: "LOVE ISLAND" },
|
||||
{ seriesId: "series-2", seriesNm: "TOP CHEF" },
|
||||
{ seriesId: "series-3", seriesNm: "BELOW DECK" },
|
||||
];
|
||||
|
||||
const SpottableDiv = Spottable('div');
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ leaveFor: { right: "" }, enterTo: "last-focused" },
|
||||
"div"
|
||||
);
|
||||
|
||||
const NBCUContent = ({
|
||||
handleItemFocus,
|
||||
spotlightId,
|
||||
shelfOrder,
|
||||
selectedPatnrId,
|
||||
shelfTitle,
|
||||
order,
|
||||
}) => {
|
||||
const [firstChk, setFirstChk] = useState(0);
|
||||
const [selectedSeriesId, setSelectedSeriesId] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
console.log('[NBCUContent] Rendered. order:', order);
|
||||
}, [order]);
|
||||
|
||||
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]);
|
||||
|
||||
return (
|
||||
<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}
|
||||
/>
|
||||
|
||||
{/* Keyword Bubble Section (Dummy) */}
|
||||
{/* <div className={css.keywordContainer}>
|
||||
|
||||
{['Action', 'Comedy', 'Drama', 'Sci-Fi', 'Thriller', 'Romance', 'Documentary'].map((keyword, index) => (
|
||||
<SpottableDiv
|
||||
key={index}
|
||||
className={css.keywordBubble}
|
||||
onClick={() => console.log(`Clicked keyword: ${keyword}`)}
|
||||
>
|
||||
{keyword}
|
||||
</SpottableDiv>
|
||||
))}
|
||||
</div> */}
|
||||
|
||||
{/* Picked For You Section Title */}
|
||||
<NBCUSectionTitle
|
||||
title={$L(STRING_CONF.PICKED_FOR_YOU)}
|
||||
data-title="picked-for-you"
|
||||
label="Picked For You Heading"
|
||||
isBlack={true}
|
||||
/>
|
||||
|
||||
{/* Series Component with Mock Data */}
|
||||
<NBCUSeries
|
||||
brandSeriesGroupInfo={MOCK_BRAND_SERIES_GROUP_INFO}
|
||||
brandSeriesInfo={MOCK_BRAND_SERIES_INFO}
|
||||
fromGNB={false}
|
||||
fromQuickMenu={false}
|
||||
handleItemFocus={_handleItemFocus}
|
||||
order={order}
|
||||
shelfOrder={shelfOrder}
|
||||
shelfTitle={shelfTitle}
|
||||
spotlightId={`${spotlightId}-series`}
|
||||
selectedPatncNm="NBCU"
|
||||
selectedPatnrId={selectedPatnrId}
|
||||
selectedSeriesId={selectedSeriesId}
|
||||
setSelectedSeriesId={setSelectedSeriesId}
|
||||
/>
|
||||
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(NBCUContent);
|
||||
@@ -0,0 +1,36 @@
|
||||
@import "../../../style/CommonStyle.module.less";
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 50px 0; // Adjust padding as needed
|
||||
}
|
||||
|
||||
.keywordContainer {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
padding: 0 60px; // Match side padding of other contents
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.keywordBubble {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px 24px;
|
||||
border-radius: 30px;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
color: #ffffff;
|
||||
font-size: 24px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
border: 2px solid transparent;
|
||||
transition: all 0.2s ease-in-out;
|
||||
|
||||
&:focus, &:hover {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
border-color: #ffffff;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import Spotlight from '@enact/spotlight';
|
||||
import SpotlightContainerDecorator from '@enact/spotlight/SpotlightContainerDecorator';
|
||||
|
||||
import TItemCardNew from '../../../../components/TItemCard/TItemCard.new';
|
||||
import TVirtualGridList from '../../../../components/TVirtualGridList/TVirtualGridList';
|
||||
import css from './NBCUList.module.less';
|
||||
|
||||
// 더미 데이터 생성
|
||||
// priceInfo format: originalPrice|discountedPrice|rewardFlag|discountAmount|discountRate|promotionCode|promotionDate
|
||||
const DUMMY_DATA = Array.from({ length: 10 }).map((_, index) => ({
|
||||
id: `nbcu-item-${index}`,
|
||||
title: `NBCU Content ${index + 1}`,
|
||||
imgUrl: 'assets/images/img-thumb-empty-product@3x.png',
|
||||
priceInfo: '$20.00|$10.00|N|$10.00|50%|PROMO|2025-12-31',
|
||||
}));
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ leaveFor: { right: '' }, enterTo: 'last-focused' },
|
||||
'div'
|
||||
);
|
||||
|
||||
const NBCUList = ({ handleItemFocus, spotlightId, shelfTitle, shelfOrder }) => {
|
||||
const renderItem = useCallback(
|
||||
({ index, ...rest }) => {
|
||||
const item = DUMMY_DATA[index];
|
||||
const labelText = `${index + 1} of ${DUMMY_DATA.length}`;
|
||||
|
||||
return (
|
||||
<TItemCardNew
|
||||
{...rest}
|
||||
key={item.id}
|
||||
imageSource={item.imgUrl}
|
||||
productName={item.title}
|
||||
priceInfo={item.priceInfo}
|
||||
spotlightId={`nbcu-spotlightId-${index}`}
|
||||
shelfId={spotlightId}
|
||||
shelfLocation={shelfOrder}
|
||||
shelfTitle={shelfTitle}
|
||||
label={labelText}
|
||||
onFocus={handleItemFocus}
|
||||
onClick={() => {
|
||||
console.log('Clicked NBCU item:', item.title);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
[handleItemFocus, spotlightId, shelfOrder, shelfTitle]
|
||||
);
|
||||
|
||||
return (
|
||||
<Container className={css.container} spotlightId="nbcu-list-id">
|
||||
<TVirtualGridList
|
||||
dataSize={DUMMY_DATA.length}
|
||||
direction="horizontal"
|
||||
itemHeight={438}
|
||||
itemWidth={324}
|
||||
spacing={18}
|
||||
renderItem={renderItem}
|
||||
className={css.tVirtualGridList}
|
||||
/>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(NBCUList);
|
||||
@@ -0,0 +1,22 @@
|
||||
@import "../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../style/utils.module.less";
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
position: relative;
|
||||
.size(@w: 100%, @h: 438px);
|
||||
padding-right: 18px;
|
||||
|
||||
// tVirtualGridListContainer
|
||||
> div:nth-child(1) {
|
||||
.size(@w: 100%, @h: inherit);
|
||||
|
||||
&.tVirtualGridList {
|
||||
padding-left: 60px;
|
||||
|
||||
> div:nth-child(3) {
|
||||
right: -18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import React, { memo } from "react";
|
||||
|
||||
import classNames from "classnames";
|
||||
|
||||
import css from "./NBCUSectionTitle.module.less";
|
||||
|
||||
export default memo(function NBCUSectionTitle({
|
||||
className,
|
||||
itemCount,
|
||||
title,
|
||||
label,
|
||||
isBlack = false,
|
||||
...rest
|
||||
}) {
|
||||
return (
|
||||
<h2
|
||||
className={classNames(css.sectionTitle, isBlack && css.blackTitle, className)}
|
||||
aria-label={label ? label : title}
|
||||
tabIndex={-1}
|
||||
aria-live="polite"
|
||||
aria-atomic="true"
|
||||
{...rest}
|
||||
>
|
||||
{title}
|
||||
{itemCount && <span>({itemCount})</span>}
|
||||
</h2>
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
@import "../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../style/utils.module.less";
|
||||
|
||||
.sectionTitle {
|
||||
position: relative;
|
||||
.flex(@justifyCenter: flex-start);
|
||||
min-height: 50px;
|
||||
font-weight: bold;
|
||||
font-size: 42px;
|
||||
color: #000000 !important;
|
||||
|
||||
&::before {
|
||||
display: inline-block;
|
||||
content: "";
|
||||
.size(@w: 6px, @h: 36px);
|
||||
margin-right: 12px;
|
||||
background-color: #000000 !important;
|
||||
}
|
||||
|
||||
span {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.blackTitle {
|
||||
color: #000000;
|
||||
|
||||
&::before {
|
||||
background-color: #000000;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
import React, { memo, useCallback, useEffect, useState } from "react";
|
||||
|
||||
import Spotlight from "@enact/spotlight";
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
|
||||
import NBCUSectionTitle from "../NBCUSectionTitle/NBCUSectionTitle";
|
||||
import { $L } from "../../../../utils/helperMethods";
|
||||
import css from "./NBCUSeries.module.less";
|
||||
import SeriesContents from "../../Series/SeriesContents/SeriesContents";
|
||||
import SeriesNav from "../../Series/SeriesNav/SeriesNav";
|
||||
|
||||
const STRING_CONF = {
|
||||
SERIES: "SERIES",
|
||||
};
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ leaveFor: { right: "" }, enterTo: "last-focused" },
|
||||
"div"
|
||||
);
|
||||
|
||||
const NBCUSeries = ({
|
||||
brandSeriesGroupInfo,
|
||||
brandSeriesInfo,
|
||||
fromGNB,
|
||||
fromQuickMenu,
|
||||
handleItemFocus,
|
||||
order,
|
||||
shelfOrder,
|
||||
shelfTitle,
|
||||
spotlightId,
|
||||
selectedPatncNm,
|
||||
selectedPatnrId,
|
||||
selectedSeriesId,
|
||||
setSelectedSeriesId,
|
||||
}) => {
|
||||
const [filteredBrandSeriesGroupInfo, setFilteredSeriesGroupInfo] = useState();
|
||||
const [firstChk, setFirstChk] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (!selectedSeriesId) {
|
||||
return setFilteredSeriesGroupInfo(brandSeriesGroupInfo);
|
||||
}
|
||||
|
||||
setFilteredSeriesGroupInfo(
|
||||
brandSeriesGroupInfo.filter(
|
||||
({ seriesId }) => seriesId === selectedSeriesId
|
||||
)
|
||||
);
|
||||
}, [brandSeriesGroupInfo, selectedSeriesId]);
|
||||
|
||||
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 = "series, 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("series, Heading1,", "");
|
||||
c.setAttribute("aria-label", newcAriaLabel);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}, [handleItemFocus, firstChk]);
|
||||
|
||||
return (
|
||||
<Container
|
||||
className={css.container}
|
||||
data-shelf-order={order}
|
||||
data-wheel-point
|
||||
spotlightId={spotlightId}
|
||||
>
|
||||
{/* <NBCUSectionTitle title={$L(STRING_CONF.SERIES)} data-title="series" isBlack={true} /> */}
|
||||
<SeriesNav
|
||||
brandSeriesInfo={brandSeriesInfo}
|
||||
fromGNB={fromGNB}
|
||||
fromQuickMenu={fromQuickMenu}
|
||||
handleItemFocus={_handleItemFocus}
|
||||
selectedPatncNm={selectedPatncNm}
|
||||
selectedPatnrId={selectedPatnrId}
|
||||
selectedSeriesId={selectedSeriesId}
|
||||
setSelectedSeriesId={setSelectedSeriesId}
|
||||
/>
|
||||
{filteredBrandSeriesGroupInfo &&
|
||||
filteredBrandSeriesGroupInfo.map(
|
||||
(
|
||||
{
|
||||
brandSeriesProductInfo,
|
||||
patnrId,
|
||||
seriesId,
|
||||
seriesImgUrl,
|
||||
seriesNm,
|
||||
},
|
||||
contentsIndex
|
||||
) => (
|
||||
<SeriesContents
|
||||
brandSeriesProductInfo={brandSeriesProductInfo}
|
||||
filteredBrandLength={filteredBrandSeriesGroupInfo.length}
|
||||
contentsIndex={contentsIndex}
|
||||
handleItemFocus={_handleItemFocus}
|
||||
isCarousel={!selectedSeriesId}
|
||||
key={`${spotlightId}-${contentsIndex}`}
|
||||
patnrId={patnrId}
|
||||
selectedPatnrId={selectedPatnrId}
|
||||
selectedSeriesId={selectedSeriesId}
|
||||
seriesId={seriesId}
|
||||
seriesImgUrl={seriesImgUrl}
|
||||
seriesNm={seriesNm}
|
||||
spotlightId={spotlightId}
|
||||
shelfOrder={shelfOrder}
|
||||
shelfTitle={shelfTitle}
|
||||
selectedPatncNm={selectedPatncNm}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(NBCUSeries);
|
||||
@@ -0,0 +1,12 @@
|
||||
@import "../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../style/utils.module.less";
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
margin-bottom: 36px;
|
||||
|
||||
h2 {
|
||||
margin-bottom: 24px;
|
||||
padding-left: 60px;
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,8 @@ import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDeco
|
||||
import TScroller from "../../../components/TScroller/TScroller";
|
||||
import useScrollTo from "../../../hooks/useScrollTo";
|
||||
import { scaleW } from "../../../utils/helperMethods";
|
||||
import QuickMenuItem from "../QuickMenu/QuickMenuItem/QuickMenuItem";
|
||||
import QuickMenuItem from "./QuickMenuItem/QuickMenuItem";
|
||||
import QuickMenuItemNBCU from "./QuickMenuItemNBCU/QuickMenuItemNBCU";
|
||||
import css from "./QuickMenu.module.less";
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
@@ -76,7 +77,32 @@ const QuickMenu = ({
|
||||
noScrollByWheel
|
||||
>
|
||||
<ul ref={ulRef}>
|
||||
{panelPatnrId === 'NBCU' ? (
|
||||
<>
|
||||
<QuickMenuItemNBCU
|
||||
itemIndex={0}
|
||||
handleItemFocus={_handleItemFocus}
|
||||
key="nbcu-item"
|
||||
resetStates={resetStates}
|
||||
scrollLeft={scrollLeft}
|
||||
selectedPatnrId={selectedPatnrId}
|
||||
label={"1 of " + (brandInfo.length + 1)}
|
||||
/>
|
||||
{brandInfo.map((brandInfoItem, itemIndex) => (
|
||||
<QuickMenuItem
|
||||
brandInfoItem={brandInfoItem}
|
||||
itemIndex={itemIndex + 1}
|
||||
handleItemFocus={_handleItemFocus}
|
||||
key={"brand-info" + itemIndex}
|
||||
resetStates={resetStates}
|
||||
scrollLeft={scrollLeft}
|
||||
selectedPatnrId={selectedPatnrId}
|
||||
label={(itemIndex + 2) + " of " + (brandInfo.length + 1)}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
brandInfo.map((brandInfoItem, itemIndex) => (
|
||||
<QuickMenuItem
|
||||
brandInfoItem={brandInfoItem}
|
||||
itemIndex={itemIndex}
|
||||
@@ -85,9 +111,10 @@ const QuickMenu = ({
|
||||
resetStates={resetStates}
|
||||
scrollLeft={scrollLeft}
|
||||
selectedPatnrId={selectedPatnrId}
|
||||
label={itemIndex * 1 + 1 + " of " + brandInfo.length}
|
||||
label={(itemIndex + 1) + " of " + brandInfo.length}
|
||||
/>
|
||||
))}
|
||||
))
|
||||
)}
|
||||
</ul>
|
||||
</TScroller>
|
||||
</Container>
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
import React, { memo, useCallback } from "react";
|
||||
|
||||
import classNames from "classnames";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
import Spottable from "@enact/spotlight/Spottable";
|
||||
|
||||
import IcPartnersDefault from "../../../../../assets/images/ic-tab-partners-default@3x.png";
|
||||
import { resetPanels, updatePanel } from "../../../../actions/panelActions";
|
||||
import CustomImage from "../../../../components/CustomImage/CustomImage";
|
||||
import useScrollReset from "../../../../hooks/useScrollReset";
|
||||
import { panel_names } from "../../../../utils/Config";
|
||||
import css from "./QuickMenuItemNBCU.module.less";
|
||||
|
||||
const SpottableComponent = Spottable("li");
|
||||
|
||||
const QuickMenuItemNBCU = ({
|
||||
itemIndex,
|
||||
handleItemFocus,
|
||||
resetStates,
|
||||
scrollLeft,
|
||||
selectedPatnrId,
|
||||
label,
|
||||
...rest
|
||||
}) => {
|
||||
const { handleScrollReset, handleStopScrolling } = useScrollReset(
|
||||
scrollLeft,
|
||||
true
|
||||
);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const panelInfo = useSelector((state) => state.panels.panels[0]?.panelInfo);
|
||||
|
||||
const patnrId = "NBCU";
|
||||
|
||||
const handleBlur = useCallback(() => {
|
||||
if (itemIndex !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
handleStopScrolling();
|
||||
}, [handleStopScrolling, itemIndex]);
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
if (patnrId === (selectedPatnrId ?? panelInfo?.patnrId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const from = "menu";
|
||||
const name = panel_names.FEATURED_BRANDS_PANEL;
|
||||
|
||||
dispatch(resetPanels([{ name }]));
|
||||
dispatch(updatePanel({ name, panelInfo: { from, patnrId } }));
|
||||
resetStates();
|
||||
}, [dispatch, patnrId, resetStates, selectedPatnrId]);
|
||||
|
||||
const handleFocus = useCallback(() => {
|
||||
if (handleItemFocus) handleItemFocus();
|
||||
|
||||
if (itemIndex !== 0) return;
|
||||
|
||||
handleScrollReset();
|
||||
}, [handleScrollReset, handleItemFocus, itemIndex]);
|
||||
|
||||
const selected =
|
||||
(selectedPatnrId ?? panelInfo?.patnrId) === patnrId ? "Selected, " : "";
|
||||
const ariaLabel = selected + "Channel NBCU, Tap " + label;
|
||||
|
||||
return (
|
||||
<SpottableComponent
|
||||
className={classNames(
|
||||
css.brand,
|
||||
(selectedPatnrId ?? panelInfo?.patnrId) === patnrId && css.selected
|
||||
)}
|
||||
data-menu-index={itemIndex}
|
||||
onBlur={handleBlur}
|
||||
onClick={handleClick}
|
||||
onFocus={handleFocus}
|
||||
spotlightId={"spotlightId-NBCU"}
|
||||
aria-label={ariaLabel}
|
||||
{...rest}
|
||||
>
|
||||
<div>
|
||||
<CustomImage
|
||||
src="assets/images/featuredBrands/image-nbcu.png"
|
||||
alt="NBCU"
|
||||
fallbackSrc={IcPartnersDefault}
|
||||
ariaLabel="NBCU"
|
||||
/>
|
||||
</div>
|
||||
</SpottableComponent>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(QuickMenuItemNBCU);
|
||||
@@ -0,0 +1,54 @@
|
||||
@import "../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../style/utils.module.less";
|
||||
|
||||
.brand {
|
||||
position: relative;
|
||||
.flex();
|
||||
.size(@w: 144px, @h: 144px);
|
||||
|
||||
> div {
|
||||
position: relative;
|
||||
// NBCU image
|
||||
> img {
|
||||
.size(@w: 120px, @h: 120px);
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
&.selected {
|
||||
// NBCU image
|
||||
.size(@w: 144px, @h: 144px);
|
||||
> div {
|
||||
&:after {
|
||||
.focused(@boxShadow: 0px, @borderRadius: 50%);
|
||||
}
|
||||
|
||||
> img {
|
||||
.size(@w: 144px, @h: 144px);
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
// NBCU image
|
||||
&:after {
|
||||
.size(@w:100%, @h:6px);
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: -18px;
|
||||
background: @PRIMARY_COLOR_RED;
|
||||
content: "";
|
||||
}
|
||||
> div {
|
||||
&:after {
|
||||
.focused(@boxShadow: 0px, @borderRadius: 50%);
|
||||
border-color: @PRIMARY_COLOR_RED;
|
||||
}
|
||||
> img {
|
||||
.size(@w: 120px, @h: 120px);
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user