[FeaturedBrandsPanel] Section 추가 및 수정

Detail Notes :

1. BestSeller section 추가
2. UpComing, TodaysDeals sections 구조 수정
This commit is contained in:
younghoon100.park
2024-02-16 10:29:17 +09:00
parent 9379b14817
commit b7daf518b0
10 changed files with 176 additions and 47 deletions

View File

@@ -0,0 +1,25 @@
import React, { useCallback } from "react";
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
import { $L } from "../../../utils/helperMethods";
import css from "./FeaturedBestSeller.module.less";
import FeaturedBestSellerList from "./FeaturedBestSellerList/FeaturedBestSellerList";
const STRING_CONF = {
BEST_SELLER: $L("BEST SELLER"),
};
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}
/>
</div>
);
}

View File

@@ -0,0 +1,10 @@
@import "../../../style/CommonStyle.module.less";
@import "../../../style/utils.module.less";
.container {
margin-bottom: 58px;
h2 {
margin-bottom: 24px;
}
}

View File

@@ -0,0 +1,68 @@
import React, { memo, useCallback } from "react";
import { VirtualGridList } from "@enact/sandstone/VirtualList";
import TItemCard from "../../../../components/TItemCard/TItemCard";
import { scaleH, scaleW } from "../../../../utils/helperMethods";
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]
);
return (
<div className={css.container}>
{brandBestSellerInfo && (
<VirtualGridList
className={css.virtualGridList}
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)}
/>
)}
</div>
);
});

View File

@@ -0,0 +1,15 @@
@import "../../../../style/CommonStyle.module.less";
@import "../../../../style/utils.module.less";
.container {
position: relative;
.size(@w: 100%, @h: 438px);
.virtualGridList {
overflow: unset;
> div {
overflow: unset !important;
}
}
}

View File

@@ -0,0 +1,6 @@
{
"main": "FeaturedBestSellerList.jsx",
"styles": [
"FeaturedBestSellerList.module.less"
]
}

View File

@@ -0,0 +1,6 @@
{
"main": "FeaturedBestSeller.jsx",
"styles": [
"FeaturedBestSeller.module.less"
]
}

View File

@@ -5,6 +5,7 @@ import { useDispatch, useSelector } from "react-redux";
import Spotlight from "@enact/spotlight"; import Spotlight from "@enact/spotlight";
import { import {
getBrandBestSeller,
getBrandLayoutInfo, getBrandLayoutInfo,
getBrandList, getBrandList,
getBrandLiveChannelInfo, getBrandLiveChannelInfo,
@@ -13,6 +14,7 @@ import {
import TBody from "../../components/TBody/TBody"; import TBody from "../../components/TBody/TBody";
import TPanel from "../../components/TPanel/TPanel"; import TPanel from "../../components/TPanel/TPanel";
import Banner from "./Banner/Banner"; import Banner from "./Banner/Banner";
import FeaturedBestSeller from "./FeaturedBestSeller/FeaturedBestSeller";
import css from "./FeaturedBrandsPanel.module.less"; import css from "./FeaturedBrandsPanel.module.less";
import LiveChannels from "./LiveChannels/LiveChannels"; import LiveChannels from "./LiveChannels/LiveChannels";
import QuickMenu from "./QuickMenu/QuickMenu"; import QuickMenu from "./QuickMenu/QuickMenu";
@@ -47,6 +49,9 @@ export default function FeaturedBrandsPanel() {
const brandTsvInfo = useSelector( const brandTsvInfo = useSelector(
(state) => state.brand.brandTsvInfoData.brandTsvInfo (state) => state.brand.brandTsvInfoData.brandTsvInfo
); );
const brandBestSellerInfo = useSelector(
(state) => state.brand.brandBestSellerData.brandBestSellerInfo
);
const [selectedPatnrId, setSelectedPatnrId] = useState(String(panelInfo)); const [selectedPatnrId, setSelectedPatnrId] = useState(String(panelInfo));
const [selectedBrandInfo, setSelectedBrandInfo] = useState(); const [selectedBrandInfo, setSelectedBrandInfo] = useState();
@@ -63,6 +68,7 @@ export default function FeaturedBrandsPanel() {
dispatch(getBrandLayoutInfo({ patnrId: selectedPatnrId })); dispatch(getBrandLayoutInfo({ patnrId: selectedPatnrId }));
dispatch(getBrandLiveChannelInfo({ patnrId: selectedPatnrId })); dispatch(getBrandLiveChannelInfo({ patnrId: selectedPatnrId }));
dispatch(getBrandTSVInfo({ patnrId: selectedPatnrId })); dispatch(getBrandTSVInfo({ patnrId: selectedPatnrId }));
dispatch(getBrandBestSeller({ patnrId: selectedPatnrId }));
} }
}, [brandInfo, dispatch, selectedPatnrId]); }, [brandInfo, dispatch, selectedPatnrId]);
@@ -107,6 +113,10 @@ export default function FeaturedBrandsPanel() {
{brandTsvInfo && isNotEmptyObject(brandTsvInfo) && ( {brandTsvInfo && isNotEmptyObject(brandTsvInfo) && (
<TodaysDeals brandTsvInfo={brandTsvInfo} /> <TodaysDeals brandTsvInfo={brandTsvInfo} />
)} )}
{brandBestSellerInfo && ( // @@pyh Todo, 추후 노출 조건 전달 (현재 노출 조건 존재 하지 않음)
<FeaturedBestSeller brandBestSellerInfo={brandBestSellerInfo} />
)}
</div> </div>
</TBody> </TBody>
</TPanel> </TPanel>

View File

@@ -9,46 +9,11 @@ const STRING_CONF = {
TODAYS_DEALS: $L("TODAY'S DEALS"), TODAYS_DEALS: $L("TODAY'S DEALS"),
}; };
// @@pyh, Todo 추후 삭제
// cpnFlag, // 쿠폰 여부 (Y or N)
// freeShippingFlag, // 무료 배송 여부 (Y or N)
// logoImgAlt, // 로고 이미지 alt 값
// logoImgNm, // 로고 이미지 이름
// logoImgPath, // 로고 이미지 경로
// offerInfo, // 제공 정보
// patncLogoPath, // 파트너사 로고 이미지 경로
// patncNm, // 파트너 이름
// patnrId, // 파트너 아이디
// prdtId, // 상품 아이디
// prdtNm, // 상품 이름
// priceInfo, // 상품 금액 정보, 할인전 금액, 할인 후(최종) 금액, 리워드 여부, save 금액, off(할인 %)
// showId, // 방송 아이디
// showNm, // 방송 이름
// showUrl, // 방송 url
// thumbnailImg, // 썸네일 이미지
// tmpltCd, // 템플릿 코드
// tmpltNm, // 템플릿 명칭
// todaySpclFlag, // Today Sepcial Value 여부 (Y or N)
export default memo(function TodaysDeals({ brandTsvInfo }) { export default memo(function TodaysDeals({ brandTsvInfo }) {
const {
freeShippingFlag,
prdtNm: productName,
priceInfo,
thumbnailImg,
todaySpclFlag: todaySpecialFlag,
} = brandTsvInfo;
return ( return (
<div className={css.container}> <div className={css.container}>
<SectionTitle title={STRING_CONF.TODAYS_DEALS} /> <SectionTitle title={STRING_CONF.TODAYS_DEALS} />
<TodaysDealsCard <TodaysDealsCard brandTsvInfo={brandTsvInfo} />
freeShippingFlag={freeShippingFlag}
imageSource={thumbnailImg}
priceInfo={priceInfo}
productName={productName}
todaySpecialFlag={todaySpecialFlag}
/>
</div> </div>
); );
}); });

View File

@@ -13,21 +13,43 @@ const STRING_CONF = {
SAVE: $L("SAVE"), SAVE: $L("SAVE"),
}; };
export default memo(function TodaysDealsCard({ // @@pyh, Todo 추후 삭제
freeShippingFlag, // cpnFlag, // 쿠폰 여부 (Y or N)
imageSource, // freeShippingFlag, // 무료 배송 여부 (Y or N)
priceInfo, // logoImgAlt, // 로고 이미지 alt 값
productName, // logoImgNm, // 로고 이미지 이름
todaySpecialFlag, // logoImgPath, // 로고 이미지 경로
...rest // offerInfo, // 제공 정보
}) { // patncLogoPath, // 파트너사 로고 이미지 경로
// patncNm, // 파트너 이름
// patnrId, // 파트너 아이디
// prdtId, // 상품 아이디
// prdtNm, // 상품 이름
// priceInfo, // 상품 금액 정보, 할인전 금액, 할인 후(최종) 금액, 리워드 여부, save 금액, off(할인 %)
// showId, // 방송 아이디
// showNm, // 방송 이름
// showUrl, // 방송 url
// thumbnailImg, // 썸네일 이미지
// tmpltCd, // 템플릿 코드
// tmpltNm, // 템플릿 명칭
// todaySpclFlag, // Today Sepcial Value 여부 (Y or N)
export default memo(function TodaysDealsCard({ brandTsvInfo, ...rest }) {
const {
freeShippingFlag,
prdtNm: productName,
priceInfo,
thumbnailImg,
todaySpclFlag: todaySpecialFlag,
} = brandTsvInfo;
const { originalPrice, discountedPrice, discountRate } = const { originalPrice, discountedPrice, discountRate } =
usePriceInfo(priceInfo); usePriceInfo(priceInfo);
return ( return (
<SpottableComponent className={css.item} {...rest}> <SpottableComponent className={css.item} {...rest}>
<div> <div>
<CustomImage src={imageSource} delay={0} alt="" /> <CustomImage src={thumbnailImg} delay={0} alt="" />
</div> </div>
<div> <div>

View File

@@ -5,12 +5,14 @@ import { $L } from "../../../utils/helperMethods";
import css from "./UpComing.module.less"; import css from "./UpComing.module.less";
import UpComingList from "./UpComingList/UpComingList"; import UpComingList from "./UpComingList/UpComingList";
const UPCOMING_STRING = "UPCOMING"; const STRING_CONF = {
UPCOMING: $L("UPCOMING"),
};
export default function UpComing({ brandLiveChannelUpcoming }) { export default function UpComing({ brandLiveChannelUpcoming }) {
return ( return (
<div className={css.container}> <div className={css.container}>
<SectionTitle title={$L(UPCOMING_STRING)} /> <SectionTitle title={STRING_CONF.UPCOMING} />
<UpComingList brandLiveChannelUpcoming={brandLiveChannelUpcoming} /> <UpComingList brandLiveChannelUpcoming={brandLiveChannelUpcoming} />
</div> </div>
); );