diff --git a/com.twin.app.shoptime/assets/images/img-home-banner-jfy-hor@3x.png b/com.twin.app.shoptime/assets/images/img-home-banner-jfy-hor@3x.png new file mode 100644 index 00000000..c6345413 Binary files /dev/null and b/com.twin.app.shoptime/assets/images/img-home-banner-jfy-hor@3x.png differ diff --git a/com.twin.app.shoptime/assets/images/img-home-banner-jfy-ver@3x.png b/com.twin.app.shoptime/assets/images/img-home-banner-jfy-ver@3x.png new file mode 100644 index 00000000..52917bdd Binary files /dev/null and b/com.twin.app.shoptime/assets/images/img-home-banner-jfy-ver@3x.png differ diff --git a/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RollingUnit.jsx b/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RollingUnit.jsx index 2c5a3ac3..4695e8c4 100644 --- a/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RollingUnit.jsx +++ b/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RollingUnit.jsx @@ -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" ? ( - ) : 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") ? ( + ) : filteredRollingData && filteredRollingData.length > 0 && filteredRollingData[startIndex].shptmLnkTpNm === "Just For You" ? ( + +
+
{$L("Just For You")}
+
+
+ {justForYouProduct ? ( + <> + {parseFloat(justForYouPriceInfo.originalPrice?.replace('$', '') || '0') === 0 + ? justForYouProduct.offerInfo + : justForYouPriceInfo.discountRate + ? justForYouPriceInfo.discountedPrice + : justForYouPriceInfo.originalPrice} + {justForYouPriceInfo.discountRate && !isHorizontal && ( + {justForYouPriceInfo.originalPrice} + )} + + ) : ( + <> + {parseFloat(originalPrice?.replace('$', '') || '0') === 0 + ? filteredRollingData[startIndex]?.offerInfo + : discountRate + ? discountedPrice + : originalPrice} + {discountRate && !isHorizontal && ( + {originalPrice} + )} + + )} +
+ {isHorizontal && justForYouProduct && parseFloat(justForYouPriceInfo.originalPrice?.replace('$', '') || '0') !== 0 && ( + {justForYouPriceInfo.originalPrice} + )} +
+ +
+ +
+ ) : null} {filteredRollingData.length !== 1 ? ( diff --git a/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RollingUnit.module.less b/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RollingUnit.module.less index 50c5e784..b01fcac3 100644 --- a/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RollingUnit.module.less +++ b/com.twin.app.shoptime/src/views/HomePanel/HomeBanner/RollingUnit.module.less @@ -237,6 +237,162 @@ left: -4px; } } + &.justforyou { + background-image: url(../../../../assets/images/img-home-banner-jfy-ver@3x.png); + background-size: 486px 858px; + background-position: left top; + border-radius: 10px; + padding: 75px 51px 0; + &.ru { + .productInfo { + .justforyouTitle { + font-size: 58px; + line-height: 60px; + font-family: @arialFontBold; + } + } + } + &.de { + .productInfo { + .justforyouTitle { + font-size: 74px !important; + line-height: 63px !important; + letter-spacing: -1px !important; + } + } + } + .productInfo { + margin-bottom: 31px; + .justforyouTitle { + .size(@w:100%,@h:132px); + font-family: Arial; + font-weight: bold; + font-size: 80px; + word-break: break-word; + font-stretch: normal; + color: #151515; + text-align: center; + line-height: 76px; + font-family: @arialFontBold; + } + .textBox { + .size(@w: 100%, @h: 80px); + margin-top: 71px; + .elip(@clamp:2); + font-weight: bold; + font-size: 30px; + color: @COLOR_GRAY06; + line-height: 1.27; + margin-bottom: 6px; + } + .accBox { + width: 100%; + text-align: center; + font-weight: bold; + font-size: 42px; + color: @PRIMARY_COLOR_RED; + line-height: 1.14; + display: inline-block; + .elip(@clamp:1); + > strong { + width: 260px; + font-size: 30px; + line-height: 1.27; + display: block; + .elip(@clamp:2); + } + .saleAccBox { + font-weight: normal; + font-size: 24px; + color: @COLOR_GRAY04; + vertical-align: middle; + text-decoration: line-through; + margin-left: 9px; + display: inline-block; + } + } + } + .itemImgBox { + > img { + .size(@w: 356px, @h: 356px); + border-radius: 12px; + border:6px solid #000; + box-sizing: content-box; + } + } + &.isHorizontal { + background-image: url(../../../../assets/images/img-home-banner-jfy-hor@3x.png); + background-size: 744px 420px; + background-position: center center; + display: flex; + padding: 0 30px 0 0; + border-radius: 10px; + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + -o-border-radius: 10px; + > div { + flex: none; + } + &.ru { + .productInfo { + .justforyouTitle { + font-size: 58px; + line-height: 60px; + font-family: @arialFontBold; + } + } + } + &.de { + .productInfo { + .justforyouTitle { + font-size: 59px !important; + line-height: 63px !important; + letter-spacing: -2px !important; + } + } + } + .productInfo { + margin-bottom: 0; + .justforyouTitle { + .size(@w:305px,@h:114px); + margin-top: 53px; + margin-left: 49px; + font-size: 66px; + word-break: break-word; + color: #151515; + text-align: left; + line-height: 57px; + font-family: @arialBlack; + } + .textBox { + .size(@w: 294px, @h: 80px); + margin: 67px 0 5px 50px; + text-align: left; + } + .accBox { + .size(@w: 320px, @h: 50px); + margin-left: 50px; + text-align: left; + display: block; + .elip(@clamp:1); + } + .saleAccBox { + color: #767676; + display: block; + text-align: left; + margin: 5px 0 0 55px; + text-decoration: line-through; + } + } + .itemImgBox { + .position(@position: absolute, @top: 47px, @left: 389px); + .size(@w: 326px, @h: 326px); + > img { + .size(@w: inherit, @h: inherit); + } + } + } + } } .arrow {