[저스트포유 배너 변경]

- 기존 image banner로들어가는부분이 아닌 today deals와 같은 포맷으로 들어가도록 변경.
 - 이미지, 데이터 불러오는부분 추가
This commit is contained in:
junghoon86.park
2025-12-09 13:54:06 +09:00
parent 439e5f46e3
commit 7f7b413aa5
4 changed files with 294 additions and 15 deletions

View File

@@ -1,23 +1,49 @@
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import classNames from 'classnames';
import { useDispatch, useSelector } from 'react-redux';
import {
useDispatch,
useSelector,
} from 'react-redux';
import Spotlight from '@enact/spotlight';
import SpotlightContainerDecorator from '@enact/spotlight/SpotlightContainerDecorator';
import SpotlightContainerDecorator
from '@enact/spotlight/SpotlightContainerDecorator';
import Spottable from '@enact/spotlight/Spottable';
import { getContainerId } from '@enact/spotlight/src/container';
import btnPlay from '../../../../assets/images/btn/btn-play-thumb-nor.png';
import defaultLogoImg from '../../../../assets/images/ic-tab-partners-default@3x.png';
import emptyHorImage from '../../../../assets/images/img-home-banner-empty-hor.png';
import emptyVerImage from '../../../../assets/images/img-home-banner-empty-ver.png';
import defaultImageItem from '../../../../assets/images/img-thumb-empty-product@3x.png';
import defaultLogoImg
from '../../../../assets/images/ic-tab-partners-default@3x.png';
import emptyHorImage
from '../../../../assets/images/img-home-banner-empty-hor.png';
import emptyVerImage
from '../../../../assets/images/img-home-banner-empty-ver.png';
import defaultImageItem
from '../../../../assets/images/img-thumb-empty-product@3x.png';
import liveShow from '../../../../assets/images/tag-liveshow.png';
import { setBannerIndex, updateHomeInfo } from '../../../actions/homeActions';
import { sendLogTopContents, sendLogTotalRecommend } from '../../../actions/logActions';
import { pushPanel, SOURCE_MENUS } from '../../../actions/panelActions';
import { startVideoPlayer, finishVideoPreview } from '../../../actions/playActions';
import {
setBannerIndex,
updateHomeInfo,
} from '../../../actions/homeActions';
import {
sendLogTopContents,
sendLogTotalRecommend,
} from '../../../actions/logActions';
import {
pushPanel,
SOURCE_MENUS,
} from '../../../actions/panelActions';
import {
finishVideoPreview,
startVideoPlayer,
} from '../../../actions/playActions';
import CustomImage from '../../../components/CustomImage/CustomImage';
import usePriceInfo from '../../../hooks/usePriceInfo';
import {
@@ -27,7 +53,10 @@ import {
LOG_TP_NO,
panel_names,
} from '../../../utils/Config';
import { $L, formatGMTString } from '../../../utils/helperMethods';
import {
$L,
formatGMTString,
} from '../../../utils/helperMethods';
import { TEMPLATE_CODE_CONF } from '../HomePanel';
import css from './RollingUnit.module.less';
@@ -81,6 +110,7 @@ export default function RollingUnit({
const introTermsAgree = useSelector((state) => state.common.optionalTermsAgree);
const homeCategory = useSelector((state) => state.home.menuData?.data?.homeCategory);
const countryCode = useSelector((state) => state.common.httpHeader.cntry_cd);
const foryouInfos = useSelector((state) => state.foryou.recommendInfo.recommendProduct);
const { userNumber } = useSelector((state) => state.common.appStatus.loginUserData);
@@ -119,7 +149,7 @@ export default function RollingUnit({
// filteredRollingDataRef 업데이트
useEffect(() => {
filteredRollingDataRef.current = filteredRollingData;
filteredRollingDataRef.current = filteredRollingData;
}, [filteredRollingData]);
const topContentsLogInfo = useMemo(() => {
@@ -333,6 +363,29 @@ export default function RollingUnit({
const { originalPrice, discountedPrice, discountRate, offerInfo } =
usePriceInfo(filteredRollingData.length > 0 ? filteredRollingData[startIndex].priceInfo : {}) || {};
// Just For You 데이터에서 첫 번째 상품 추출
const justForYouProduct = useMemo(() => {
if (foryouInfos && foryouInfos.length > 0) {
const justForYouShelf = foryouInfos.find(
(shelf) => shelf.recommendTpCd === 'JUSTFORYOU'
);
if (justForYouShelf && justForYouShelf.productInfos && justForYouShelf.productInfos.length > 0) {
return justForYouShelf.productInfos[0];
}
}
return null;
}, [foryouInfos]);
// Just For You 상품의 가격 정보
const justForYouPriceInfo = usePriceInfo(
justForYouProduct && justForYouProduct.priceInfo ? justForYouProduct.priceInfo : ''
) || {
originalPrice: '',
discountedPrice: '',
discountRate: null,
offerInfo: '',
};
const handlePushPanel = useCallback(
(name, panelInfo) => {
const isDetailPanel = name === panel_names.DETAIL_PANEL;
@@ -582,7 +635,8 @@ export default function RollingUnit({
/>
) : null}
{filteredRollingData && filteredRollingData.length > 0 && filteredRollingData[startIndex].shptmBanrTpNm === 'Image Banner' ? (
{/* 일반 Image Banner (Just For You, Today's Deals 제외) */}
{filteredRollingData && filteredRollingData.length > 0 && filteredRollingData[startIndex].shptmBanrTpNm === 'Image Banner' && filteredRollingData[startIndex].shptmLnkTpNm !== 'Just For You' && filteredRollingData[startIndex].shptmLnkTpNm !== "Today's Deals" ? (
<SpottableComponent
className={classNames(css.itemBox, isHorizontal && css.isHorizontal)}
onClick={imageBannerClick}
@@ -700,7 +754,7 @@ export default function RollingUnit({
)}
</div>
</SpottableComponent>
) : filteredRollingData && filteredRollingData.length > 0 && filteredRollingData[startIndex].shptmBanrTpNm === "Today's Deals" ? (
) : filteredRollingData && filteredRollingData.length > 0 && (filteredRollingData[startIndex].shptmBanrTpNm === "Today's Deals" || filteredRollingData[startIndex].shptmLnkTpNm === "Today's Deals") ? (
<SpottableComponent
className={classNames(
css.itemBox,
@@ -754,6 +808,75 @@ export default function RollingUnit({
/>
</div>
</SpottableComponent>
) : filteredRollingData && filteredRollingData.length > 0 && filteredRollingData[startIndex].shptmLnkTpNm === "Just For You" ? (
<SpottableComponent
className={classNames(
css.itemBox,
css.justforyou,
countryCode === 'RU' ? css.ru : '',
countryCode === 'DE' ? css.de : '',
isHorizontal && css.isHorizontal
)}
onClick={imageBannerClick}
onFocus={onFocus}
onBlur={onBlur}
spotlightId={spotlightId}
spotlightDisabled={contentsFocus}
aria-label={
justForYouProduct?.prdtNm
? justForYouProduct.prdtNm
: filteredRollingData[startIndex].tmnlImgNm
}
>
<div className={css.productInfo}>
<div className={css.justforyouTitle}>{$L("Just For You")}</div>
<div
className={css.textBox}
dangerouslySetInnerHTML={{
__html: `${justForYouProduct?.prdtNm || filteredRollingData[startIndex].prdtNm}`,
}}
/>
<div className={css.accBox}>
{justForYouProduct ? (
<>
{parseFloat(justForYouPriceInfo.originalPrice?.replace('$', '') || '0') === 0
? justForYouProduct.offerInfo
: justForYouPriceInfo.discountRate
? justForYouPriceInfo.discountedPrice
: justForYouPriceInfo.originalPrice}
{justForYouPriceInfo.discountRate && !isHorizontal && (
<span className={css.saleAccBox}>{justForYouPriceInfo.originalPrice}</span>
)}
</>
) : (
<>
{parseFloat(originalPrice?.replace('$', '') || '0') === 0
? filteredRollingData[startIndex]?.offerInfo
: discountRate
? discountedPrice
: originalPrice}
{discountRate && !isHorizontal && (
<span className={css.saleAccBox}>{originalPrice}</span>
)}
</>
)}
</div>
{isHorizontal && justForYouProduct && parseFloat(justForYouPriceInfo.originalPrice?.replace('$', '') || '0') !== 0 && (
<span className={css.saleAccBox}>{justForYouPriceInfo.originalPrice}</span>
)}
</div>
<div className={css.itemImgBox}>
<CustomImage
alt=""
delay={0}
animationSpeed="fast"
src={justForYouProduct?.imgUrl || filteredRollingData[startIndex]?.tmnlImgPath}
fallbackSrc={defaultImageItem}
ariaLabel={justForYouProduct?.prdtNm || filteredRollingData[startIndex]?.tmnlImgNm}
/>
</div>
</SpottableComponent>
) : null}
{filteredRollingData.length !== 1 ? (