[FeaturedBrandsPanel] section, SERIES 추가 및 수정
Detail Notes : 1. SERIES, Nav & Contents 추가 2. 각 section, 불필요 re-rendering 방지 작업
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import React from "react";
|
||||
import React, { memo } from "react";
|
||||
|
||||
import css from "./Banner.module.less";
|
||||
|
||||
export default function Banner({ brandTopImgInfo, selectedBrandInfo }) {
|
||||
export default memo(function Banner({ brandTopImgInfo, selectedBrandInfo }) {
|
||||
const { topImgAlt, topImgPath } = brandTopImgInfo;
|
||||
const { logoImgAlt, logoImgPath, patncNm } = selectedBrandInfo;
|
||||
|
||||
@@ -15,4 +15,4 @@ export default function Banner({ brandTopImgInfo, selectedBrandInfo }) {
|
||||
<img src={topImgPath} alt={topImgAlt} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from "react";
|
||||
import React, { memo } from "react";
|
||||
|
||||
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
|
||||
import { $L } from "../../../utils/helperMethods";
|
||||
@@ -9,11 +9,11 @@ const STRING_CONF = {
|
||||
BEST_SELLER: $L("BEST SELLER"),
|
||||
};
|
||||
|
||||
export default function FeaturedBestSeller({ brandBestSellerInfo }) {
|
||||
export default memo(function FeaturedBestSeller({ brandBestSellerInfo }) {
|
||||
return (
|
||||
<div className={css.container}>
|
||||
<SectionTitle title={STRING_CONF.BEST_SELLER} />
|
||||
<FeaturedBestSellerList brandBestSellerInfo={brandBestSellerInfo} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
@@ -14,7 +14,9 @@ import {
|
||||
getBrandTSVInfo,
|
||||
} from "../../actions/brandActions";
|
||||
import TBody from "../../components/TBody/TBody";
|
||||
import TButton, { TYPES } from "../../components/TButton/TButton";
|
||||
import TPanel from "../../components/TPanel/TPanel";
|
||||
import useScrollTo from "../../hooks/useScrollTo";
|
||||
import Banner from "./Banner/Banner";
|
||||
import FeaturedBestSeller from "./FeaturedBestSeller/FeaturedBestSeller";
|
||||
import css from "./FeaturedBrandsPanel.module.less";
|
||||
@@ -36,6 +38,8 @@ const isNotEmptyObject = (object) => {
|
||||
};
|
||||
|
||||
export default function FeaturedBrandsPanel() {
|
||||
const { getScrollTo, scrollTop } = useScrollTo();
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const panelInfo = useSelector((state) => state.panels.panels[0].panelInfo);
|
||||
@@ -92,10 +96,11 @@ export default function FeaturedBrandsPanel() {
|
||||
const [selectedSeriesId, setSelectedSeriesId] = useState();
|
||||
const [selectedCatCdLv1, setSelectedCatCdLv1] = useState();
|
||||
const [selectedCatCdLv2, setSelectedCatCdLv2] = useState();
|
||||
const [targetId, setTargetId] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
if (!brandInfo) {
|
||||
console.log("@@ [initial sideEffect]");
|
||||
// console.log("@@ [initial sideEffect]");
|
||||
|
||||
dispatch(getBrandList());
|
||||
}
|
||||
@@ -103,7 +108,7 @@ export default function FeaturedBrandsPanel() {
|
||||
|
||||
useEffect(() => {
|
||||
if (brandInfo && selectedPatnrId) {
|
||||
console.log("@@ [patnrId sideEffect]");
|
||||
// console.log("@@ [patnrId sideEffect]");
|
||||
|
||||
setSelectedBrandInfo(findItemByPatnrId(brandInfo, selectedPatnrId));
|
||||
setSelectedCatCd();
|
||||
@@ -133,7 +138,7 @@ export default function FeaturedBrandsPanel() {
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedCatCd) {
|
||||
console.log("@@ [catCd sideEffect]");
|
||||
// console.log("@@ [catCd sideEffect]");
|
||||
|
||||
dispatch(
|
||||
getBrandRecommendedShowInfo({
|
||||
@@ -146,7 +151,7 @@ export default function FeaturedBrandsPanel() {
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedHstNm) {
|
||||
console.log("@@ [hstNm sideEffect]");
|
||||
// console.log("@@ [hstNm sideEffect]");
|
||||
|
||||
dispatch(
|
||||
getBrandCreatorsInfo({ patnrId: selectedPatnrId, hstNm: selectedHstNm })
|
||||
@@ -156,22 +161,20 @@ export default function FeaturedBrandsPanel() {
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedSeriesId) {
|
||||
console.log("@@ [seriedId sideEffect]");
|
||||
// console.log("@@ [seriedId sideEffect]");
|
||||
|
||||
dispatch(
|
||||
dispatch(
|
||||
getBrandSeriesInfo({
|
||||
patnrId: selectedPatnrId,
|
||||
seriesId: selectedSeriesId,
|
||||
})
|
||||
)
|
||||
getBrandSeriesInfo({
|
||||
patnrId: selectedPatnrId,
|
||||
seriesId: selectedSeriesId,
|
||||
})
|
||||
);
|
||||
}
|
||||
}, [selectedSeriesId, dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedCatCdLv1 || selectedCatCdLv1 === "") {
|
||||
console.log("@@ [catCdLv1 sideEffect]");
|
||||
// console.log("@@ [catCdLv1 sideEffect]");
|
||||
|
||||
dispatch(
|
||||
getBrandCategoryInfo({
|
||||
@@ -185,7 +188,7 @@ export default function FeaturedBrandsPanel() {
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedCatCdLv2 || selectedCatCdLv2 === "") {
|
||||
console.log("@@ [catCdLv2 sideEffect]");
|
||||
// console.log("@@ [catCdLv2 sideEffect]");
|
||||
|
||||
dispatch(
|
||||
getBrandCategoryInfo({
|
||||
@@ -201,10 +204,18 @@ export default function FeaturedBrandsPanel() {
|
||||
// @@pyh Todo, 진입시 focuse 기능 추가
|
||||
}, []);
|
||||
|
||||
const handleTopButtonClick = useCallback(() => {
|
||||
if (!targetId) {
|
||||
return scrollTop();
|
||||
}
|
||||
|
||||
// @@pyh Todo, 상단 Top Contents의 불확실성으로 Scenario 개정 후 작업
|
||||
}, [targetId]);
|
||||
|
||||
return (
|
||||
/* scenario page 98 */
|
||||
<TPanel className={css.container}>
|
||||
<TBody className={css.tBody}>
|
||||
<TBody className={css.tBody} cbScrollTo={getScrollTo}>
|
||||
{brandInfo && brandInfo.length > 1 && (
|
||||
<QuickMenu
|
||||
brandInfo={brandInfo}
|
||||
@@ -265,7 +276,13 @@ export default function FeaturedBrandsPanel() {
|
||||
|
||||
{brandSeriesGroupInfo?.length > 0 &&
|
||||
brandSeriesInfo && ( // @@pyh Todo, 현재 데이터 존재 하지 않음 ,노출 조건 문의 (현재 노출 조건 존재 하지 않음)
|
||||
<Series />
|
||||
<Series
|
||||
brandSeriesGroupInfo={brandSeriesGroupInfo}
|
||||
brandSeriesInfo={brandSeriesInfo}
|
||||
selectedPatnrId={selectedPatnrId}
|
||||
selectedSeriesId={selectedSeriesId}
|
||||
setSelectedSeriesId={setSelectedSeriesId}
|
||||
/>
|
||||
)}
|
||||
|
||||
{brandCategoryInfo &&
|
||||
@@ -279,6 +296,12 @@ export default function FeaturedBrandsPanel() {
|
||||
setSelectedCatCdLv2={setSelectedCatCdLv2}
|
||||
/>
|
||||
)}
|
||||
|
||||
<TButton
|
||||
onClick={handleTopButtonClick}
|
||||
size={null}
|
||||
type={TYPES.topButton}
|
||||
/>
|
||||
</TBody>
|
||||
</TPanel>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from "react";
|
||||
import React, { memo } from "react";
|
||||
|
||||
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
|
||||
import { $L } from "../../../utils/helperMethods";
|
||||
@@ -11,7 +11,7 @@ const STRING_CONF = {
|
||||
CATEGORY: $L("CATEGORY"),
|
||||
};
|
||||
|
||||
export default function FeaturedCategory({
|
||||
export default memo(function FeaturedCategory({
|
||||
brandCategoryInfo,
|
||||
brandCategoryProductInfo,
|
||||
selectedCatCdLv1,
|
||||
@@ -19,12 +19,12 @@ export default function FeaturedCategory({
|
||||
setSelectedCatCdLv1,
|
||||
setSelectedCatCdLv2,
|
||||
}) {
|
||||
const catCdLv1Array = brandCategoryInfo.map((obj) => obj["catCdLv1"]);
|
||||
const catCdArrayLv1 = brandCategoryInfo.map((obj) => obj["catCdLv1"]);
|
||||
const brandCategoryProductInfoLv1 = brandCategoryProductInfo.filter(
|
||||
({ catCd }) => catCdLv1Array.includes(catCd)
|
||||
({ catCd }) => catCdArrayLv1.includes(catCd)
|
||||
);
|
||||
const brandCategoryProductInfoLv2 = brandCategoryProductInfo.filter(
|
||||
({ catCd }) => !catCdLv1Array.includes(catCd)
|
||||
({ catCd }) => !catCdArrayLv1.includes(catCd)
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -87,4 +87,4 @@ export default function FeaturedCategory({
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from "react";
|
||||
import React, { memo } from "react";
|
||||
|
||||
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
|
||||
import { $L } from "../../../utils/helperMethods";
|
||||
@@ -10,7 +10,7 @@ const STRING_CONF = {
|
||||
FEATURED_CREATORS: $L("FEATURED CREATORS"),
|
||||
};
|
||||
|
||||
export default function FeaturedCreators({
|
||||
export default memo(function FeaturedCreators({
|
||||
brandCreatorsInfo,
|
||||
barndCreatorsShowInfo,
|
||||
selectedHstNm,
|
||||
@@ -66,4 +66,4 @@ export default function FeaturedCreators({
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useCallback } from "react";
|
||||
import React, { memo, useCallback } from "react";
|
||||
|
||||
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
|
||||
import { $L } from "../../../utils/helperMethods";
|
||||
@@ -18,9 +18,11 @@ import LiveVideoCard from "./LiveVideoCard/LiveVideoCard";
|
||||
// soldoutFlag,
|
||||
// }
|
||||
|
||||
const LIVE_CHANNELS_STRING = "LIVE CHANNELS";
|
||||
const STRING_CONF = {
|
||||
LIVE_CHANNELS: $L("LIVE CHANNELS"),
|
||||
};
|
||||
|
||||
export default function LiveChannels({ brandChanInfo, brandChannelCnt }) {
|
||||
export default memo(function LiveChannels({ brandChanInfo, brandChannelCnt }) {
|
||||
const {
|
||||
alamDispFlag, // UpComming 알람 여부
|
||||
brandProductInfo, // 상품 정보 Array
|
||||
@@ -47,7 +49,7 @@ export default function LiveChannels({ brandChanInfo, brandChannelCnt }) {
|
||||
<>
|
||||
{brandChannelCnt > 0 && (
|
||||
<div className={css.container}>
|
||||
<SectionTitle title={$L(LIVE_CHANNELS_STRING)} />
|
||||
<SectionTitle title={STRING_CONF.LIVE_CHANNELS} />
|
||||
|
||||
{brandChannelCnt === 1 && (
|
||||
// @@pyh Todo, 오류 또는 장애 발생으로, Live방송이 나오지 않을 경우 처리 (Scenario, page 102)
|
||||
@@ -81,4 +83,4 @@ export default function LiveChannels({ brandChanInfo, brandChannelCnt }) {
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useCallback } from "react";
|
||||
import React, { memo, useCallback } from "react";
|
||||
|
||||
import { VirtualGridList } from "@enact/sandstone/VirtualList";
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
@@ -17,7 +17,7 @@ const Container = SpotlightContainerDecorator(
|
||||
"nav"
|
||||
);
|
||||
|
||||
export default function QuickMenu({
|
||||
export default memo(function QuickMenu({
|
||||
brandInfo,
|
||||
selectedPatnrId,
|
||||
setSelectedPatnrId,
|
||||
@@ -58,4 +58,4 @@ export default function QuickMenu({
|
||||
)}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -9,6 +9,10 @@ import css from "./QuickMenuItem.module.less";
|
||||
|
||||
const SpottableComponent = Spottable("div");
|
||||
|
||||
const STRING_CONF = {
|
||||
NEW: $L("NEW"),
|
||||
};
|
||||
|
||||
export default memo(function QuickMenuItem({
|
||||
brandInfo,
|
||||
index,
|
||||
@@ -42,7 +46,7 @@ export default memo(function QuickMenuItem({
|
||||
{...rest}
|
||||
>
|
||||
<img src={logoImgPath} alt={logoImgAlt} />
|
||||
{newFlag === "Y" && <div>{$L("NEW")}</div>}
|
||||
{newFlag === "Y" && <div>{STRING_CONF.NEW}</div>}
|
||||
<span />
|
||||
</SpottableComponent>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from "react";
|
||||
import React, { memo } from "react";
|
||||
|
||||
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
|
||||
import { $L } from "../../../utils/helperMethods";
|
||||
@@ -10,7 +10,7 @@ const STRING_CONF = {
|
||||
RECOMMENDED_SHOWS: $L("RECOMMENDED SHOWS"),
|
||||
};
|
||||
|
||||
export default function RecommendedShows({
|
||||
export default memo(function RecommendedShows({
|
||||
brandRecommendedShowCategoryInfo,
|
||||
brandRecommendedShowInfo,
|
||||
selectedCatCd,
|
||||
@@ -53,4 +53,4 @@ export default function RecommendedShows({
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,17 +1,61 @@
|
||||
import React from "react";
|
||||
import React, { memo } from "react";
|
||||
|
||||
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
|
||||
import { $L } from "../../../utils/helperMethods";
|
||||
import css from "./Series.module.less";
|
||||
import SeriesContents from "./SeriesContents/SeriesContents";
|
||||
import SeriesNav from "./SeriesNav/SeriesNav";
|
||||
|
||||
const STRING_CONF = {
|
||||
SERIES: $L("SERIES"),
|
||||
};
|
||||
|
||||
export default function Series() {
|
||||
export default memo(function Series({
|
||||
brandSeriesGroupInfo,
|
||||
brandSeriesInfo,
|
||||
selectedPatnrId,
|
||||
selectedSeriesId,
|
||||
setSelectedSeriesId,
|
||||
}) {
|
||||
return (
|
||||
<div className={css.container}>
|
||||
<SectionTitle title={STRING_CONF.SERIES} />
|
||||
<SeriesNav
|
||||
brandSeriesInfo={brandSeriesInfo}
|
||||
selectedPatnrId={selectedPatnrId}
|
||||
selectedSeriesId={selectedSeriesId}
|
||||
setSelectedSeriesId={setSelectedSeriesId}
|
||||
/>
|
||||
{brandSeriesGroupInfo &&
|
||||
brandSeriesGroupInfo.map(
|
||||
(
|
||||
// @@pyh Todo, delete comment, later
|
||||
{
|
||||
brandSeriesProductInfo,
|
||||
// logoImgAlt,
|
||||
// logoImgNm,
|
||||
// logoImgPath,
|
||||
patnrId,
|
||||
// prdtTotalCnt,
|
||||
seriesId,
|
||||
seriesImgUrl,
|
||||
seriesNm,
|
||||
},
|
||||
index
|
||||
) => (
|
||||
<SeriesContents
|
||||
brandSeriesProductInfo={brandSeriesProductInfo}
|
||||
index={index}
|
||||
key={"brandSeriesGroupInfo-" + index}
|
||||
patnrId={patnrId}
|
||||
selectedPatnrId={selectedPatnrId}
|
||||
selectedSeriesId={selectedSeriesId}
|
||||
seriesId={seriesId}
|
||||
seriesImgUrl={seriesImgUrl}
|
||||
seriesNm={seriesNm}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import React from "react";
|
||||
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
import Spottable from "@enact/spotlight/Spottable";
|
||||
|
||||
import css from "./SeriesContents.module.less";
|
||||
import SeriesProductList from "./SeriesProductList/SeriesProductList";
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ leaveFor: { right: "" }, enterTo: "last-focused" },
|
||||
"div"
|
||||
);
|
||||
|
||||
const SpottableComponent = Spottable("figure");
|
||||
|
||||
export default function SeriesContents({
|
||||
brandSeriesProductInfo,
|
||||
index,
|
||||
patnrId,
|
||||
selectedPatnrId,
|
||||
selectedSeriesId,
|
||||
seriesId,
|
||||
seriesImgUrl,
|
||||
seriesNm,
|
||||
}) {
|
||||
return (
|
||||
<Container
|
||||
className={css.container}
|
||||
id={"featuredSeriesContentsId-" + index}
|
||||
spotlightId={"featuredSeriesContentsId-" + index}
|
||||
>
|
||||
<h3>{seriesNm}</h3>
|
||||
<div>
|
||||
<SpottableComponent>
|
||||
<img src={seriesImgUrl} alt={seriesNm} />
|
||||
</SpottableComponent>
|
||||
<SeriesProductList
|
||||
brandSeriesProductInfo={brandSeriesProductInfo}
|
||||
selectedSeriesId={selectedSeriesId}
|
||||
selectedPatnrId={selectedPatnrId}
|
||||
patnrId={patnrId}
|
||||
/>
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
@import "../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../style/utils.module.less";
|
||||
|
||||
.container {
|
||||
margin-bottom: 36px;
|
||||
padding-left: 60px;
|
||||
|
||||
// contents title
|
||||
h3 {
|
||||
margin-bottom: 18px;
|
||||
.font(@fontFamily: @arialFontBold, @fontSize: 36px);
|
||||
color: @COLOR_GRAY08;
|
||||
}
|
||||
|
||||
// contents content
|
||||
> div:nth-child(2) {
|
||||
display: flex;
|
||||
.size(@w: 100%, @h:438px);
|
||||
|
||||
figure {
|
||||
position: relative;
|
||||
.size(@w: 663px, @h:438px);
|
||||
padding: 18px;
|
||||
background-color: @COLOR_WHITE;
|
||||
border: solid 1px @COLOR_WHITE;
|
||||
border-radius: 12px;
|
||||
|
||||
img {
|
||||
.size(@w: 627px, @h:402px);
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
&::after {
|
||||
.focused(@boxShadow: 22px, @borderRadius: 12px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
import React, { useCallback, useEffect } from "react";
|
||||
|
||||
import { useDispatch } from "react-redux";
|
||||
|
||||
import { pushPanel } from "../../../../../actions/panelActions";
|
||||
import TItemCard from "../../../../../components/TItemCard/TItemCard";
|
||||
import TVirtualGridList from "../../../../../components/TVirtualGridList/TVirtualGridList";
|
||||
import useScrollTo from "../../../../../hooks/useScrollTo";
|
||||
import { panel_names } from "../../../../../utils/Config";
|
||||
import css from "./SeriesProductList.module.less";
|
||||
|
||||
export default function SeriesProductList({
|
||||
brandSeriesProductInfo,
|
||||
selectedPatnrId,
|
||||
selectedSeriesId,
|
||||
patnrId,
|
||||
}) {
|
||||
const { getScrollTo, scrollLeft } = useScrollTo();
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
scrollLeft();
|
||||
}, [selectedPatnrId, selectedSeriesId]);
|
||||
|
||||
const renderItem = useCallback(
|
||||
({ index, ...rest }) => {
|
||||
const { prdtId, prdtImgUrl, prdtNm, priceInfo, soldoutFlag } =
|
||||
brandSeriesProductInfo[index];
|
||||
|
||||
const handleClick = () => {
|
||||
dispatch(
|
||||
pushPanel({
|
||||
name: panel_names.DETAIL_PANEL,
|
||||
panelInfo: { patnrId, prdtId },
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<TItemCard
|
||||
imageAlt={prdtNm}
|
||||
imageSource={prdtImgUrl}
|
||||
onClick={handleClick}
|
||||
priceInfo={priceInfo}
|
||||
productId={prdtId}
|
||||
productName={prdtNm}
|
||||
soldoutFlag={soldoutFlag}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
},
|
||||
[brandSeriesProductInfo, dispatch, patnrId]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={css.container}>
|
||||
{brandSeriesProductInfo && (
|
||||
<TVirtualGridList
|
||||
cbScrollTo={getScrollTo}
|
||||
className={css.tVirtualGridList}
|
||||
dataSize={brandSeriesProductInfo.length}
|
||||
direction="horizontal"
|
||||
itemHeight={438}
|
||||
itemWidth={324}
|
||||
spacing={18}
|
||||
renderItem={renderItem}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
@import "../../../../../style/utils.module.less";
|
||||
|
||||
.container {
|
||||
.flex();
|
||||
width: calc(100% - 663px);
|
||||
padding-left: 18px;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"main": "SeriesProductList.jsx",
|
||||
"styles": [
|
||||
"SeriesProductList.module.less"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"main": "SeriesContents.jsx",
|
||||
"styles": [
|
||||
"SeriesContents.module.less"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import React, { useCallback, useEffect } from "react";
|
||||
|
||||
import Scroller from "@enact/sandstone/Scroller";
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
|
||||
import TButton, { TYPES } from "../../../../components/TButton/TButton";
|
||||
import useScrollReset from "../../../../hooks/useScrollReset";
|
||||
import useScrollTo from "../../../../hooks/useScrollTo";
|
||||
import { $L } from "../../../../utils/helperMethods";
|
||||
import css from "./SeriesNav.module.less";
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ leaveFor: { right: "" }, enterTo: "last-focused" },
|
||||
"nav"
|
||||
);
|
||||
|
||||
const STRING_CONF = {
|
||||
ALL: $L("ALL"),
|
||||
};
|
||||
|
||||
export default function SeriesNav({
|
||||
brandSeriesInfo,
|
||||
selectedPatnrId,
|
||||
selectedSeriesId,
|
||||
setSelectedSeriesId,
|
||||
}) {
|
||||
const { getScrollTo, scrollLeft } = useScrollTo();
|
||||
const { handleScrollReset, handleStopScrolling } = useScrollReset(
|
||||
scrollLeft,
|
||||
true
|
||||
);
|
||||
|
||||
const handleBlur = useCallback(() => {
|
||||
handleStopScrolling();
|
||||
}, []);
|
||||
|
||||
const handleClick = useCallback((seriesId) => {
|
||||
setSelectedSeriesId(seriesId);
|
||||
}, []);
|
||||
|
||||
const handleFocus = useCallback(() => {
|
||||
handleScrollReset();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
scrollLeft();
|
||||
}, [selectedPatnrId]);
|
||||
return (
|
||||
<Container className={css.nav}>
|
||||
<Scroller
|
||||
cbScrollTo={getScrollTo}
|
||||
direction="horizontal"
|
||||
horizontalScrollbar="hidden"
|
||||
noScrollByWheel
|
||||
scrollMode="translate"
|
||||
>
|
||||
<ul>
|
||||
<li>
|
||||
<TButton
|
||||
className={!selectedSeriesId && css.selected}
|
||||
onBlur={handleBlur}
|
||||
onClick={() => handleClick("")}
|
||||
onFocus={handleFocus}
|
||||
selected={!selectedSeriesId}
|
||||
type={TYPES.oneDepthCategory}
|
||||
>
|
||||
{STRING_CONF.ALL}
|
||||
</TButton>
|
||||
</li>
|
||||
{brandSeriesInfo &&
|
||||
brandSeriesInfo.map(({ seriesId, seriesNm }, index) => (
|
||||
<li key={"brandSeriesInfo-" + index}>
|
||||
<TButton
|
||||
className={
|
||||
selectedSeriesId &&
|
||||
selectedSeriesId === seriesId &&
|
||||
css.selected
|
||||
}
|
||||
onClick={() => handleClick(seriesId)}
|
||||
selected={selectedSeriesId && selectedSeriesId === seriesId}
|
||||
type={TYPES.oneDepthCategory}
|
||||
>
|
||||
{seriesNm}
|
||||
</TButton>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Scroller>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
@import "../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../style/utils.module.less";
|
||||
|
||||
.nav {
|
||||
.size(@w: 100%, @h: 162px);
|
||||
margin-bottom: 12px;
|
||||
background-color: #ddd;
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: inherit;
|
||||
padding-left: 60px;
|
||||
border-bottom: 18px solid @BG_COLOR_01;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
right: -100%;
|
||||
bottom: 0;
|
||||
.size(@w: 100%, @h: 18px);
|
||||
background-color: @BG_COLOR_01;
|
||||
content: "";
|
||||
}
|
||||
|
||||
li {
|
||||
margin-right: 12px;
|
||||
|
||||
> div {
|
||||
position: relative;
|
||||
|
||||
&.selected {
|
||||
&::before {
|
||||
position: absolute;
|
||||
bottom: -62px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
.size(@w: 0, @h: 0);
|
||||
border-top: 18px solid #ddd;
|
||||
border-right: 18px solid transparent;
|
||||
border-bottom: 18px solid transparent;
|
||||
border-left: 18px solid transparent;
|
||||
content: "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"main": "SeriesNav.jsx",
|
||||
"styles": [
|
||||
"SeriesNav.module.less"
|
||||
]
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from "react";
|
||||
import React, { memo } from "react";
|
||||
|
||||
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
|
||||
import { $L } from "../../../utils/helperMethods";
|
||||
@@ -9,11 +9,11 @@ const STRING_CONF = {
|
||||
UPCOMING: $L("UPCOMING"),
|
||||
};
|
||||
|
||||
export default function UpComing({ brandLiveChannelUpcoming }) {
|
||||
export default memo(function UpComing({ brandLiveChannelUpcoming }) {
|
||||
return (
|
||||
<div className={css.container}>
|
||||
<SectionTitle title={STRING_CONF.UPCOMING} />
|
||||
<UpComingList brandLiveChannelUpcoming={brandLiveChannelUpcoming} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user