[FeaturedBrandsPanel] RecommendedShows 추가, TVirtualGridList 변경 반영
Detail Notes :
This commit is contained in:
@@ -1,44 +1,60 @@
|
||||
import React, { memo, useCallback } from "react";
|
||||
import React, { useCallback } 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 { panel_names } from "../../../../utils/Config";
|
||||
import css from "./FeaturedBestSellerList.module.less";
|
||||
|
||||
export default memo(function FeaturedBestSellerList({ brandBestSellerInfo }) {
|
||||
export default function FeaturedBestSellerList({ brandBestSellerInfo }) {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const handleClick = useCallback(
|
||||
(brandBestSellerInfo) => {
|
||||
const { patnrId, prdtId } = brandBestSellerInfo;
|
||||
const renderItem = useCallback(
|
||||
({ index, ...rest }) => {
|
||||
const { imgUrl, patnrId, prdtNm, prdtId, priceInfo, rankOrd } =
|
||||
brandBestSellerInfo[index];
|
||||
|
||||
dispatch(
|
||||
pushPanel({
|
||||
name: panel_names.DETAIL_PANEL,
|
||||
panelInfo: { patnrId, prdtId },
|
||||
})
|
||||
const handleClick = () => {
|
||||
dispatch(
|
||||
pushPanel({
|
||||
name: panel_names.DETAIL_PANEL,
|
||||
panelInfo: { patnrId, prdtId },
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<TItemCard
|
||||
imageAlt={prdtNm}
|
||||
imageSource={imgUrl}
|
||||
isBestSeller
|
||||
rank={rankOrd}
|
||||
onClick={handleClick}
|
||||
priceInfo={priceInfo}
|
||||
productId={prdtId}
|
||||
productName={prdtNm}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
},
|
||||
[dispatch, brandBestSellerInfo]
|
||||
[brandBestSellerInfo, dispatch]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={css.container}>
|
||||
{brandBestSellerInfo && (
|
||||
<></>
|
||||
// <TVirtualGridList
|
||||
// className={css.tVirtualGridList}
|
||||
// dataSize={brandBestSellerInfo.length}
|
||||
// direction="horizontal"
|
||||
// items={brandBestSellerInfo}
|
||||
// itemHeight={438}
|
||||
// itemWidth={324}
|
||||
// onClick={handleClick}
|
||||
// spacing={18}
|
||||
// />
|
||||
<TVirtualGridList
|
||||
className={css.tVirtualGridList}
|
||||
dataSize={brandBestSellerInfo.length}
|
||||
direction="horizontal"
|
||||
itemHeight={438}
|
||||
itemWidth={324}
|
||||
spacing={18}
|
||||
renderItem={renderItem}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@ import React, { useEffect, useState } from "react";
|
||||
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
import Spotlight from "@enact/spotlight";
|
||||
|
||||
import {
|
||||
getBrandBestSeller,
|
||||
getBrandLayoutInfo,
|
||||
@@ -62,31 +60,39 @@ export default function FeaturedBrandsPanel() {
|
||||
(state) => state.brand.brandRecommendedShowInfoData.brandRecommendedShowInfo
|
||||
);
|
||||
|
||||
const [selectedPatnrId, setSelectedPatnrId] = useState(String(panelInfo));
|
||||
const [selectedPatnrId, setSelectedPatnrId] = useState(panelInfo.toString());
|
||||
const [selectedBrandInfo, setSelectedBrandInfo] = useState();
|
||||
const [selectedCatCd, setSelectedCatCd] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
if (!brandInfo) {
|
||||
console.log("@@ [initial sideEffect]");
|
||||
|
||||
dispatch(getBrandList());
|
||||
}
|
||||
}, [brandInfo, dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("@@ [patnrId sideEffect]");
|
||||
if (brandInfo && selectedPatnrId) {
|
||||
console.log("@@ [patnrId sideEffect]");
|
||||
|
||||
setSelectedBrandInfo(findItemByPatnrId(brandInfo, selectedPatnrId));
|
||||
setSelectedCatCd();
|
||||
|
||||
dispatch(getBrandLayoutInfo({ patnrId: selectedPatnrId }));
|
||||
dispatch(getBrandLiveChannelInfo({ patnrId: selectedPatnrId }));
|
||||
dispatch(getBrandTSVInfo({ patnrId: selectedPatnrId }));
|
||||
dispatch(getBrandBestSeller({ patnrId: selectedPatnrId }));
|
||||
dispatch(getBrandRecommendedShowInfo({ patnrId: selectedPatnrId }));
|
||||
dispatch(
|
||||
getBrandRecommendedShowInfo({ patnrId: selectedPatnrId, catCd: "" })
|
||||
);
|
||||
}
|
||||
}, [brandInfo, dispatch, selectedPatnrId]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("@@ [catCd sideEffect]");
|
||||
if (selectedCatCd) {
|
||||
console.log("@@ [catCd sideEffect]");
|
||||
|
||||
dispatch(
|
||||
getBrandRecommendedShowInfo({
|
||||
catCd: selectedCatCd,
|
||||
|
||||
@@ -62,7 +62,10 @@ export default function LiveChannels({ brandChanInfo, brandChannelCnt }) {
|
||||
/>
|
||||
|
||||
{brandProductInfo && (
|
||||
<LiveProductList brandProductInfo={brandProductInfo} />
|
||||
<LiveProductList
|
||||
brandProductInfo={brandProductInfo}
|
||||
patnrId={patnrId}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -1,23 +1,58 @@
|
||||
import React from "react";
|
||||
import React, { useCallback } from "react";
|
||||
|
||||
import { TYPES } from "../../../../components/TItemCard/TItemCard";
|
||||
import { useDispatch } from "react-redux";
|
||||
|
||||
import { pushPanel } from "../../../../actions/panelActions";
|
||||
import TItemCard, { TYPES } from "../../../../components/TItemCard/TItemCard";
|
||||
import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
|
||||
import { panel_names } from "../../../../utils/Config";
|
||||
import css from "./LiveProductList.module.less";
|
||||
|
||||
export default function LiveProductList({ brandProductInfo }) {
|
||||
export default function LiveProductList({ brandProductInfo, patnrId }) {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const renderItem = useCallback(
|
||||
({ index, ...rest }) => {
|
||||
const { prdtId, prdtImgUrl, prdtNm, priceInfo, soldoutFlag } =
|
||||
brandProductInfo[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}
|
||||
type={TYPES.horizontal}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
},
|
||||
[brandProductInfo, dispatch, patnrId]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={css.container}>
|
||||
{brandProductInfo && (
|
||||
<></>
|
||||
// <TVirtualGridList
|
||||
// className={css.tVirtualGridList}
|
||||
// dataSize={brandProductInfo.length}
|
||||
// items={brandProductInfo}
|
||||
// itemHeight={236}
|
||||
// itemType={TYPES.horizontal}
|
||||
// itemWidth={660}
|
||||
// spacing={12}
|
||||
// />
|
||||
<TVirtualGridList
|
||||
className={css.tVirtualGridList}
|
||||
dataSize={brandProductInfo.length}
|
||||
itemHeight={236}
|
||||
itemWidth={660}
|
||||
spacing={12}
|
||||
renderItem={renderItem}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,48 +1,39 @@
|
||||
import React, { memo } from "react";
|
||||
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
|
||||
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
|
||||
import { $L } from "../../../utils/helperMethods";
|
||||
import css from "./RecommendedShows.module.less";
|
||||
import RecommendedShowsContents from "./RecommendedShowsContents/RecommendedShowsContents";
|
||||
import RecommendedShowsNav from "./RecommendedShowsNav/RecommendedShowsNav";
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ leaveFor: { right: "" }, enterTo: "last-focused" },
|
||||
"div"
|
||||
);
|
||||
|
||||
const STRING_CONF = {
|
||||
RECOMMENDED_SHOWS: $L("RECOMMENDED SHOWS"),
|
||||
};
|
||||
|
||||
{
|
||||
/* <TButton
|
||||
onClick={() => handleClick(catCd)}
|
||||
selected={selectedCatCd === String(catCd)}
|
||||
type={TYPES.oneDepthCategory}
|
||||
>
|
||||
{catNm}
|
||||
</TButton>
|
||||
<TButton
|
||||
selected={selectedCatCd === String(catCd)}
|
||||
size={null}
|
||||
color={null}
|
||||
type={TYPES.twoDepthCategory}
|
||||
withMarquee
|
||||
>
|
||||
{catNm}
|
||||
</TButton> */
|
||||
}
|
||||
|
||||
export default function RecommendedShows({
|
||||
export default memo(function RecommendedShows({
|
||||
brandRecommendedShowCategoryInfo,
|
||||
brandRecommendedShowInfo,
|
||||
selectedCatCd,
|
||||
setSelectedCatCd,
|
||||
}) {
|
||||
return (
|
||||
<div className={css.container}>
|
||||
<Container className={css.container}>
|
||||
<SectionTitle title={STRING_CONF.RECOMMENDED_SHOWS} />
|
||||
|
||||
<RecommendedShowsNav
|
||||
brandRecommendedShowCategoryInfo={brandRecommendedShowCategoryInfo}
|
||||
selectedCatCd={selectedCatCd}
|
||||
setSelectedCatCd={setSelectedCatCd}
|
||||
/>
|
||||
</div>
|
||||
<RecommendedShowsContents
|
||||
brandRecommendedShowInfo={brandRecommendedShowInfo}
|
||||
/>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import React from "react";
|
||||
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
|
||||
import TItemCard, { TYPES } from "../../../../components/TItemCard/TItemCard";
|
||||
import css from "./RecommendedShowsContents.module.less";
|
||||
import RecommendedShowsProductList from "./RecommendedShowsProductList/RecommendedShowsProductList";
|
||||
|
||||
const ContentsWrap = SpotlightContainerDecorator(
|
||||
{ leaveFor: { right: "" }, enterTo: "last-focused" },
|
||||
"div"
|
||||
);
|
||||
|
||||
export default function RecommendedShowsContents({ brandRecommendedShowInfo }) {
|
||||
return (
|
||||
<div className={css.container}>
|
||||
{brandRecommendedShowInfo &&
|
||||
brandRecommendedShowInfo.map(
|
||||
(
|
||||
{ brandRecommendedShowProductInfo, patnrId, showNm, thumbnailUrl },
|
||||
index
|
||||
) => (
|
||||
<ContentsWrap
|
||||
className={css.contentsWrap}
|
||||
key={"brandRecommendedShowInfo-" + index}
|
||||
>
|
||||
<TItemCard
|
||||
imageAlt={showNm}
|
||||
imageSource={thumbnailUrl}
|
||||
nonPosition
|
||||
productName={showNm}
|
||||
type={TYPES.videoShow}
|
||||
/>
|
||||
<RecommendedShowsProductList
|
||||
brandRecommendedShowProductInfo={
|
||||
brandRecommendedShowProductInfo
|
||||
}
|
||||
patnrId={patnrId}
|
||||
/>
|
||||
</ContentsWrap>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
@import "../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../style/utils.module.less";
|
||||
|
||||
.container {
|
||||
.flex(@direction: column, @justifyCenter: flex-start);
|
||||
width: 100%;
|
||||
padding-left: 60px;
|
||||
|
||||
.contentsWrap {
|
||||
display: flex;
|
||||
.size(@w: 100%, @h:438px);
|
||||
margin-bottom: 36px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
import React, { useCallback } 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 { panel_names } from "../../../../../utils/Config";
|
||||
import css from "./RecommendedShowsProductList.module.less";
|
||||
|
||||
export default function RecommendedShowsProductList({
|
||||
brandRecommendedShowProductInfo,
|
||||
patnrId,
|
||||
}) {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const renderItem = useCallback(
|
||||
({ index, ...rest }) => {
|
||||
const { imgUrl, prdtId, prdtNm, priceInfo, soldoutFlag } =
|
||||
brandRecommendedShowProductInfo[index];
|
||||
|
||||
const handleClick = () => {
|
||||
dispatch(
|
||||
pushPanel({
|
||||
name: panel_names.DETAIL_PANEL,
|
||||
panelInfo: { patnrId, prdtId },
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<TItemCard
|
||||
imageAlt={prdtNm}
|
||||
imageSource={imgUrl}
|
||||
onClick={handleClick}
|
||||
priceInfo={priceInfo}
|
||||
productId={prdtId}
|
||||
productName={prdtNm}
|
||||
soldoutFlag={soldoutFlag}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
},
|
||||
[brandRecommendedShowProductInfo, dispatch, patnrId]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={css.container}>
|
||||
{brandRecommendedShowProductInfo && (
|
||||
<TVirtualGridList
|
||||
className={css.tVirtualGridList}
|
||||
dataSize={brandRecommendedShowProductInfo.length}
|
||||
direction="horizontal"
|
||||
itemHeight={438}
|
||||
itemWidth={324}
|
||||
spacing={18}
|
||||
renderItem={renderItem}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
@import "../../../../../style/utils.module.less";
|
||||
|
||||
.container {
|
||||
.flex();
|
||||
overflow: hidden;
|
||||
width: calc(100% - 546px);
|
||||
padding-left: 18px;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"main": "RecommendedShowsProductList.jsx",
|
||||
"styles": [
|
||||
"RecommendedShowsProductList.module.less"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"main": "RecommendedShowsProductContents.jsx",
|
||||
"styles": [
|
||||
"RecommendedShowsProductContents.module.less"
|
||||
]
|
||||
}
|
||||
@@ -1,12 +1,18 @@
|
||||
import React, { useCallback } 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 css from "./RecommendedShowsNav.module.less";
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ leaveFor: { right: "" }, enterTo: "last-focused" },
|
||||
"nav"
|
||||
);
|
||||
|
||||
export default function RecommendedShowsNav({
|
||||
brandRecommendedShowCategoryInfo,
|
||||
selectedCatCd,
|
||||
@@ -22,11 +28,12 @@ export default function RecommendedShowsNav({
|
||||
if (index !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
handleStopScrolling();
|
||||
}, []);
|
||||
|
||||
const handleClick = useCallback((catCd) => {
|
||||
setSelectedCatCd(String(catCd));
|
||||
setSelectedCatCd(catCd);
|
||||
}, []);
|
||||
|
||||
const handleFocus = useCallback((index) => {
|
||||
@@ -38,7 +45,7 @@ export default function RecommendedShowsNav({
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<nav className={css.nav}>
|
||||
<Container className={css.nav}>
|
||||
<Scroller
|
||||
cbScrollTo={getScrollTo}
|
||||
direction="horizontal"
|
||||
@@ -51,10 +58,15 @@ export default function RecommendedShowsNav({
|
||||
brandRecommendedShowCategoryInfo.map(({ catNm, catCd }, index) => (
|
||||
<li key={"brandRecommendedShowCategoryInfo-" + index}>
|
||||
<TButton
|
||||
className={selectedCatCd === catCd.toString() && css.selected}
|
||||
onBlur={() => handleBlur(index)}
|
||||
onClick={() => handleClick(catCd)}
|
||||
onClick={() => handleClick(catCd.toString())}
|
||||
onFocus={() => handleFocus(index)}
|
||||
selected={selectedCatCd === String(catCd)}
|
||||
selected={
|
||||
selectedCatCd
|
||||
? selectedCatCd === catCd.toString()
|
||||
: index === 0
|
||||
}
|
||||
type={TYPES.oneDepthCategory}
|
||||
>
|
||||
{catNm}
|
||||
@@ -63,6 +75,6 @@ export default function RecommendedShowsNav({
|
||||
))}
|
||||
</ul>
|
||||
</Scroller>
|
||||
</nav>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,17 +2,47 @@
|
||||
@import "../../../../style/utils.module.less";
|
||||
|
||||
.nav {
|
||||
.size(@w: 100%, @h: 144px);
|
||||
background-color: #dddddd;
|
||||
.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: "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,6 @@ const STRING_CONF = {
|
||||
const SpottableComponent = Spottable("div");
|
||||
|
||||
export default memo(function UpComingCard({ hstNm, showNm, strtDt, ...rest }) {
|
||||
for (let key in rest) delete rest[key];
|
||||
|
||||
const [isFocused, setIsFocused] = useState(false);
|
||||
const [isSelected, setIsSelected] = useState(false);
|
||||
|
||||
|
||||
@@ -1,24 +1,32 @@
|
||||
import React from "react";
|
||||
import React, { useCallback } from "react";
|
||||
|
||||
import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
|
||||
import UpComingCard from "./UpComingCard/UpComingCard";
|
||||
import css from "./UpComingList.module.less";
|
||||
|
||||
export default function UpComingList({ brandLiveChannelUpcoming }) {
|
||||
const renderItem = useCallback(
|
||||
({ index, ...rest }) => {
|
||||
const { hstNm, showNm, strtDt } = brandLiveChannelUpcoming[index];
|
||||
return (
|
||||
<UpComingCard hstNm={hstNm} showNm={showNm} strtDt={strtDt} {...rest} />
|
||||
);
|
||||
},
|
||||
[brandLiveChannelUpcoming]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={css.container}>
|
||||
{brandLiveChannelUpcoming && (
|
||||
<></>
|
||||
// <TVirtualGridList
|
||||
// className={css.tVirtualGridList}
|
||||
// dataSize={brandLiveChannelUpcoming.length}
|
||||
// direction="horizontal"
|
||||
// items={brandLiveChannelUpcoming}
|
||||
// itemCard={UpComingCard}
|
||||
// itemHeight={344}
|
||||
// itemWidth={480}
|
||||
// spacing={18}
|
||||
// />
|
||||
<TVirtualGridList
|
||||
className={css.tVirtualGridList}
|
||||
dataSize={brandLiveChannelUpcoming.length}
|
||||
direction="horizontal"
|
||||
itemHeight={344}
|
||||
itemWidth={480}
|
||||
spacing={18}
|
||||
renderItem={renderItem}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user