[FeaturedBrandsPanel] component, props 수정

Detail Notes :

1.  TVirtualGridList 반영
2. props 변경
This commit is contained in:
younghoon100.park
2024-02-20 16:26:20 +09:00
parent 6bdd51cdeb
commit 58058f6f67
16 changed files with 84 additions and 235 deletions

View File

@@ -1,4 +1,4 @@
import React, { useCallback } from "react";
import React from "react";
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
import { $L } from "../../../utils/helperMethods";
@@ -10,16 +10,10 @@ const STRING_CONF = {
};
export default function FeaturedBestSeller({ brandBestSellerInfo }) {
// @@pyh Todo, DetailPanel 생성 이후 action 추가
const handleCardClick = useCallback((productId) => {}, []);
return (
<div className={css.container}>
<SectionTitle title={STRING_CONF.BEST_SELLER} />
<FeaturedBestSellerList
brandBestSellerInfo={brandBestSellerInfo}
onCardClick={handleCardClick}
/>
<FeaturedBestSellerList brandBestSellerInfo={brandBestSellerInfo} />
</div>
);
}

View File

@@ -1,66 +1,20 @@
import React, { memo, useCallback } from "react";
import React, { memo } from "react";
import { VirtualGridList } from "@enact/sandstone/VirtualList";
import TItemCard from "../../../../components/TItemCard/TItemCard";
import { scaleH, scaleW } from "../../../../utils/helperMethods";
import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
import css from "./FeaturedBestSellerList.module.less";
const LIST_ITEM_CONF = {
ITEM_WIDTH: 324,
ITEM_HEIGHT: 438,
SAPCING: 18,
};
export default memo(function FeaturedBestSellerList({
brandBestSellerInfo,
onCardClick,
}) {
const renderItem = useCallback(
({ index, ...rest }) => {
const {
imgUrl,
prdtId: productId,
prdtNm: productName,
priceInfo,
rankOrd: rankOrder,
soldoutFlag,
} = brandBestSellerInfo[index];
return (
<TItemCard
key={productId}
imageAlt={productName}
imageSource={imgUrl}
isBestSeller
onCardClick={onCardClick}
priceInfo={priceInfo}
productId={productId}
productName={productName}
rank={rankOrder}
{...rest}
soldoutFlag={soldoutFlag}
/>
);
},
[brandBestSellerInfo, onCardClick]
);
export default memo(function FeaturedBestSellerList({ brandBestSellerInfo }) {
return (
<div className={css.container}>
{brandBestSellerInfo && (
<VirtualGridList
className={css.virtualGridList}
<TVirtualGridList
className={css.tVirtualGridList}
dataSize={brandBestSellerInfo.length}
direction="horizontal"
horizontalScrollbar="hidden"
itemRenderer={renderItem}
itemSize={{
minWidth: scaleW(LIST_ITEM_CONF.ITEM_WIDTH),
minHeight: scaleH(LIST_ITEM_CONF.ITEM_HEIGHT),
}}
noScrollByWheel
scrollMode="translate"
spacing={scaleW(LIST_ITEM_CONF.SAPCING)}
items={brandBestSellerInfo}
itemHeight={438}
itemWidth={324}
spacing={18}
/>
)}
</div>

View File

@@ -5,7 +5,7 @@
position: relative;
.size(@w: 100%, @h: 438px);
.virtualGridList {
.tVirtualGridList {
overflow: unset;
> div {

View File

@@ -64,7 +64,7 @@ export default function FeaturedBrandsPanel() {
const [selectedPatnrId, setSelectedPatnrId] = useState(String(panelInfo));
const [selectedBrandInfo, setSelectedBrandInfo] = useState();
const [brandCategoryInfo, setBrandCategoryInfo] = useState();
const [selectedCatCd, setSelectedCatCd] = useState();
useEffect(() => {
if (!brandInfo) {
@@ -73,7 +73,7 @@ export default function FeaturedBrandsPanel() {
}, [brandInfo, dispatch]);
useEffect(() => {
console.log("@@ [brand sideEffect]");
console.log("@@ [patnrId sideEffect]");
if (brandInfo && selectedPatnrId) {
setSelectedBrandInfo(findItemByPatnrId(brandInfo, selectedPatnrId));
dispatch(getBrandLayoutInfo({ patnrId: selectedPatnrId }));
@@ -85,23 +85,20 @@ export default function FeaturedBrandsPanel() {
}, [brandInfo, dispatch, selectedPatnrId]);
useEffect(() => {
console.log("@@ [category sideEffect]");
if (brandCategoryInfo) {
console.log("@@ [catCd sideEffect]");
if (selectedCatCd) {
dispatch(
getBrandRecommendedShowInfo({
catCd: brandCategoryInfo,
catCd: selectedCatCd,
patnrId: selectedPatnrId,
})
);
}
}, [brandCategoryInfo, dispatch]);
}, [selectedCatCd, dispatch]);
useEffect(() => {
// @@pyh Todo, loading 적용 이후 loading으로 조건 추가
if (selectedPatnrId) {
Spotlight.focus("spotlight" + selectedPatnrId);
}
}, [selectedPatnrId]);
// @@pyh Todo, 진입시 focuse 기능 추가
}, []);
return (
/* scenario page 98 */
@@ -149,7 +146,7 @@ export default function FeaturedBrandsPanel() {
brandRecommendedShowCategoryInfo
}
brandRecommendedShowInfo={brandRecommendedShowInfo}
setBrandCategoryInfo={setBrandCategoryInfo}
setSelectedCatCd={setSelectedCatCd}
/>
)}
</div>

View File

@@ -43,9 +43,6 @@ export default function LiveChannels({ brandChanInfo, brandChannelCnt }) {
vtctpYn, // 영상 세로형 여부
} = brandChanInfo;
// @@pyh Todo, scenario page 100, thumbnail click → 영상 full 화면 이동 및 해당 상품 focuse
const handleCardClick = useCallback((productId) => {}, []);
return (
<>
{brandChannelCnt > 0 && (
@@ -57,18 +54,15 @@ export default function LiveChannels({ brandChanInfo, brandChannelCnt }) {
// 라이브 영상이 1개일 경우
<div>
<LiveVideoCard
endTime={endDt}
liveChannelCount={brandChannelCnt}
startTime={strtDt}
thumbnailSource={thumbnailImgPath}
title={showNm}
brandChannelCnt={brandChannelCnt}
endDt={endDt}
showNm={showNm}
strtDt={strtDt}
thumbnailImgPath={thumbnailImgPath}
/>
{brandProductInfo && (
<LiveProductList
brandProductInfo={brandProductInfo}
onCardClick={handleCardClick}
/>
<LiveProductList brandProductInfo={brandProductInfo} />
)}
</div>
)}

View File

@@ -1,62 +1,21 @@
import React, { useCallback } from "react";
import React from "react";
import { VirtualGridList } from "@enact/sandstone/VirtualList";
import TItemCard from "../../../../components/TItemCard/TItemCard";
import { scaleH, scaleW } from "../../../../utils/helperMethods";
import { TYPES } from "../../../../components/TItemCard/TItemCard";
import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
import css from "./LiveProductList.module.less";
const LIST_ITEM_CONF = {
ITEM_WIDTH: 660,
ITEM_HEIGHT: 236,
SAPCING: 12,
};
export default function LiveProductList({ brandProductInfo, onCardClick }) {
const renderItem = useCallback(
({ index, ...rest }) => {
const {
prdtImgUrl,
prdtId: productId,
prdtNm: productName,
priceInfo,
soldoutFlag,
} = brandProductInfo[index];
return (
<TItemCard
key={productId}
imageAlt={productName}
imageSource={prdtImgUrl}
onCardClick={onCardClick}
priceInfo={priceInfo}
productId={productId}
productName={productName}
{...rest}
soldoutFlag={soldoutFlag}
type="horizontal"
/>
);
},
[brandProductInfo, onCardClick]
);
export default function LiveProductList({ brandProductInfo }) {
return (
<div className={css.container}>
{brandProductInfo && (
<VirtualGridList
className={css.virtualGridList}
<TVirtualGridList
className={css.tVirtualGridList}
dataSize={brandProductInfo.length}
direction="vertical"
itemRenderer={renderItem}
itemSize={{
minWidth: scaleW(LIST_ITEM_CONF.ITEM_WIDTH),
minHeight: scaleH(LIST_ITEM_CONF.ITEM_HEIGHT),
}}
noScrollByWheel
scrollMode="translate"
spacing={scaleW(LIST_ITEM_CONF.SAPCING)}
verticalScrollbar="hidden"
items={brandProductInfo}
itemHeight={236}
itemType={TYPES.horizontal}
itemWidth={660}
spacing={12}
/>
)}
</div>

View File

@@ -14,7 +14,7 @@
}
// @@pyh Todo, box-shadow issue
// .virtualGridList {
// .tVirtualGridList {
// overflow: unset;
// > div {

View File

@@ -16,14 +16,14 @@ const WARNING_MESSAGE =
"This program was previously recorded. Offers, pricing, and availability may have changed.";
export default memo(function LiveVideoCard({
endTime,
liveChannelCount,
brandChannelCnt,
endDt,
onVideoCardBlur,
onVideoCardClick,
onVideoCardFocus,
startTime,
thumbnailSource,
title,
showNm,
strtDt,
thumbnailImgPath,
...rest
}) {
const [isFocused, setIsFocused] = useState(false);
@@ -44,26 +44,26 @@ export default memo(function LiveVideoCard({
return (
<SpottableComponent
className={css.container}
className={css.card}
{...rest}
onBlur={handleBlur}
onClick={handleClick}
onFocus={handleFocus}
>
<img src={thumbnailSource} alt={title} />
<img src={thumbnailImgPath} alt={showNm} />
<div>
<div>
<img src={IcLiveShow} alt={$L(LIVE_SHOW_STRING)} />
<div>
<h3>{title}</h3>
<h3>{showNm}</h3>
<time>
{startTime} ~ {endTime}
{strtDt} ~ {endDt}
</time>
</div>
</div>
{liveChannelCount && liveChannelCount === 1 && (
{brandChannelCnt && brandChannelCnt === 1 && (
// @@pyh, live 방송이라는 조건으로 변경
<div>
<img src={IcWarning} alt={$L(WARNING_STRING)} />

View File

@@ -1,7 +1,7 @@
@import "../../../../style/CommonStyle.module.less";
@import "../../../../style/utils.module.less";
.container {
.card {
/* normal */
position: relative;
z-index: 10;

View File

@@ -1,4 +1,4 @@
import React, { useCallback, useEffect } from "react";
import React, { useCallback } from "react";
import { VirtualGridList } from "@enact/sandstone/VirtualList";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
@@ -23,17 +23,6 @@ export default function QuickMenu({
setSelectedPatnrId,
...rest
}) {
const handleQuickMenuClick = useCallback(
(patnrId) => {
if (selectedPatnrId === patnrId) {
return;
}
setSelectedPatnrId(patnrId);
},
[selectedPatnrId]
);
const renderItem = useCallback(
({ index, ...rest }) => {
return (
@@ -41,12 +30,12 @@ export default function QuickMenu({
brandInfo={brandInfo}
index={index}
selectedPatnrId={selectedPatnrId}
onQuickMenuClick={handleQuickMenuClick}
setSelectedPatnrId={setSelectedPatnrId}
{...rest}
/>
);
},
[brandInfo, selectedPatnrId, handleQuickMenuClick]
[brandInfo, selectedPatnrId]
);
return (

View File

@@ -12,15 +12,19 @@ const SpottableComponent = Spottable("div");
export default memo(function QuickMenuItem({
brandInfo,
index,
onQuickMenuClick,
selectedPatnrId,
setSelectedPatnrId,
...rest
}) {
const { logoImgAlt, logoImgPath, newFlag, patnrId } = brandInfo[index];
const handleClick = useCallback(
(patnrId) => {
onQuickMenuClick && onQuickMenuClick(patnrId);
if (selectedPatnrId === patnrId) {
return;
}
setSelectedPatnrId(patnrId);
},
[selectedPatnrId]
);
@@ -28,14 +32,14 @@ export default memo(function QuickMenuItem({
return (
<SpottableComponent
className={classNames(
css.item,
css.brand,
patnrId === selectedPatnrId && css.selected
)}
id={patnrId}
key={patnrId}
onClick={() => handleClick(patnrId)}
spotlightId={"spotlightId-" + patnrId}
{...rest}
spotlightId={"spotlight" + patnrId}
>
<img src={logoImgPath} alt={logoImgAlt} />
{newFlag === "Y" && <div>{$L("NEW")}</div>}

View File

@@ -1,7 +1,7 @@
@import "../../../../style/CommonStyle.module.less";
@import "../../../../style/utils.module.less";
.item {
.brand {
/* normal */
position: relative;
.size(@w: 138px, @h: 138px);

View File

@@ -11,11 +11,10 @@ const STRING_CONF = {
export default function RecommendedShows({
brandRecommendedShowCategoryInfo,
brandRecommendedShowInfo,
setBrandCategoryInfo,
setSelectedCatCd,
}) {
const handleClick = (catCd) => {
console.log("@@catCd", catCd);
setBrandCategoryInfo(String(catCd));
setSelectedCatCd(String(catCd));
};
return (

View File

@@ -18,22 +18,15 @@ const STRING_CONF = {
const SpottableComponent = Spottable("div");
export default memo(function UpComingCard({
hostName,
onUpComingCardBlur,
onUpComingCardClick,
onUpComingCardFocus,
showName,
startTime,
...rest
}) {
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);
const handleBlur = useCallback(() => {
setIsFocused(false);
onUpComingCardBlur && onUpComingCardBlur();
}, [onUpComingCardBlur]);
}, []);
const handleClick = useCallback(() => {
if (isSelected) {
@@ -45,18 +38,15 @@ export default memo(function UpComingCard({
} else {
setIsSelected(true);
}
onUpComingCardClick && onUpComingCardClick();
}, [isSelected, onUpComingCardClick]);
}, [isSelected]);
const handleFocus = useCallback(() => {
setIsFocused(true);
onUpComingCardFocus && onUpComingCardFocus();
}, [onUpComingCardFocus]);
}, []);
return (
<SpottableComponent
className={classNames(css.item, isSelected && css.selected)}
className={classNames(css.card, isSelected && css.selected)}
onBlur={handleBlur}
onClick={handleClick}
onFocus={handleFocus}
@@ -75,11 +65,11 @@ export default memo(function UpComingCard({
<time>
{
// @@pyh, Todo 시간 변환
startTime
strtDt
}
</time>
<h3>{showName}</h3>
<p>{STRING_CONF.WITH_HOST + " " + hostName}</p>
<h3>{showNm}</h3>
<p>{STRING_CONF.WITH_HOST + " " + hstNm}</p>
{isFocused && (
<button type="button">

View File

@@ -1,7 +1,7 @@
@import "../../../../../style/CommonStyle.module.less";
@import "../../../../../style/utils.module.less";
.item {
.card {
/* normal */
position: relative;
.size(@w: 480px, @h: 344px);

View File

@@ -1,53 +1,22 @@
import React, { useCallback } from "react";
import React from "react";
import { VirtualGridList } from "@enact/sandstone/VirtualList";
import { scaleH, scaleW } from "../../../../utils/helperMethods";
import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
import UpComingCard from "./UpComingCard/UpComingCard";
import css from "./UpComingList.module.less";
const LIST_ITEM_CONF = {
ITEM_WIDTH: 480,
ITEM_HEIGHT: 344,
SAPCING: 18,
};
export default function UpComingList({ brandLiveChannelUpcoming }) {
const renderItem = useCallback(
({ index, ...rest }) => {
const {
hstNm: hostName,
showNm: showName,
strtDt: startTime,
} = brandLiveChannelUpcoming[index];
return (
<UpComingCard
{...rest}
hostName={hostName}
showName={showName}
startTime={startTime}
/>
);
},
[brandLiveChannelUpcoming]
);
return (
<div className={css.container}>
{brandLiveChannelUpcoming && (
<VirtualGridList
className={css.virtualGridList}
<TVirtualGridList
className={css.tVirtualGridList}
dataSize={brandLiveChannelUpcoming.length}
direction="horizontal"
itemRenderer={renderItem}
itemSize={{
minWidth: scaleW(LIST_ITEM_CONF.ITEM_WIDTH),
minHeight: scaleH(LIST_ITEM_CONF.ITEM_HEIGHT),
}}
noScrollByWheel
scrollMode="translate"
spacing={scaleW(LIST_ITEM_CONF.SAPCING)}
verticalScrollbar="hidden"
items={brandLiveChannelUpcoming}
itemCard={UpComingCard}
itemHeight={344}
itemWidth={480}
spacing={18}
/>
)}
</div>