[251019] fix: TabContainerV2 , ShopNowContents YouMayAlsoConents처리

🕐 커밋 시간: 2025. 10. 19. 15:45:14

📊 변경 통계:
  • 총 파일: 6개
  • 추가: +220줄
  • 삭제: -62줄

📝 수정된 파일:
  ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContents/ShopNowContents.jsx
  ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContents/ShopNowContents.v2.module.less
  ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/ShopNowContainer.module.less
  ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/ShopNowItem.module.less
  ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/TabContainer.v2.jsx
  ~ com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/v2/TabContainer.v2.module.less

🔧 함수 변경 내용:
  📄 com.twin.app.shoptime/src/views/PlayerPanel/PlayerTabContents/TabContents/ShopNowContents.jsx (javascript):
     Added: handleItemClick()
This commit is contained in:
2025-10-19 15:45:18 +09:00
parent 1f795ef61c
commit cd1788ad4f
6 changed files with 240 additions and 139 deletions

View File

@@ -1,61 +1,37 @@
import React, { import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import { import { useDispatch, useSelector } from 'react-redux';
useDispatch,
useSelector,
} from 'react-redux';
import { Job } from '@enact/core/util'; import { Job } from '@enact/core/util';
import Spotlight from '@enact/spotlight'; import Spotlight from '@enact/spotlight';
import SpotlightContainerDecorator import SpotlightContainerDecorator from '@enact/spotlight/SpotlightContainerDecorator';
from '@enact/spotlight/SpotlightContainerDecorator'; import { getContainerNode, setContainerLastFocusedElement } from '@enact/spotlight/src/container';
import {
getContainerNode,
setContainerLastFocusedElement,
} from '@enact/spotlight/src/container';
import { sendLogTotalRecommend } from '../../../../actions/logActions'; import { sendLogTotalRecommend } from '../../../../actions/logActions';
import { pushPanel } from '../../../../actions/panelActions'; import { pushPanel } from '../../../../actions/panelActions';
import { hidePlayerOverlays } from '../../../../actions/videoPlayActions'; import { hidePlayerOverlays } from '../../../../actions/videoPlayActions';
import TItemCard, { TYPES } from '../../../../components/TItemCard/TItemCard'; import TItemCard, { TYPES } from '../../../../components/TItemCard/TItemCard';
import TVirtualGridList import TVirtualGridList from '../../../../components/TVirtualGridList/TVirtualGridList';
from '../../../../components/TVirtualGridList/TVirtualGridList';
import useScrollTo from '../../../../hooks/useScrollTo'; import useScrollTo from '../../../../hooks/useScrollTo';
import { import { LOG_CONTEXT_NAME, LOG_MENU, LOG_MESSAGE_ID, panel_names } from '../../../../utils/Config';
LOG_CONTEXT_NAME,
LOG_MENU,
LOG_MESSAGE_ID,
panel_names,
} from '../../../../utils/Config';
import { scaleH } from '../../../../utils/helperMethods'; import { scaleH } from '../../../../utils/helperMethods';
import ListEmptyContents import ListEmptyContents from '../TabContents/ListEmptyContents/ListEmptyContents';
from '../TabContents/ListEmptyContents/ListEmptyContents';
import css1 from './ShopNowContents.module.less'; import css1 from './ShopNowContents.module.less';
import cssV2 from './ShopNowContents.v2.module.less'; import cssV2 from './ShopNowContents.v2.module.less';
const extractPriceInfo = (priceInfo) => { const extractPriceInfo = (priceInfo) => {
if (!priceInfo) if (!priceInfo) return { originalPrice: '', discountedPrice: '', discountRate: '' };
return { originalPrice: "", discountedPrice: "", discountRate: "" };
const parts = priceInfo.split("|").map((part) => part.trim()); const parts = priceInfo.split('|').map((part) => part.trim());
return { return {
originalPrice: parts[0] || "", originalPrice: parts[0] || '',
discountedPrice: parts[1] || "", discountedPrice: parts[1] || '',
discountRate: parts[4] || "", discountRate: parts[4] || '',
}; };
}; };
const Container = SpotlightContainerDecorator( const Container = SpotlightContainerDecorator({ enterTo: 'last-focused' }, 'div');
{ enterTo: "last-focused" },
"div"
);
export default function ShopNowContents({ export default function ShopNowContents({
shopNowInfo, shopNowInfo,
videoVerticalVisible, videoVerticalVisible,
@@ -65,16 +41,40 @@ export default function ShopNowContents({
panelInfo, panelInfo,
tabTitle, tabTitle,
version = 1, version = 1,
direction = "vertical", direction = 'vertical',
}) { }) {
const css = version === 2 ? cssV2 : css1; const css = version === 2 ? cssV2 : css1;
const { getScrollTo, scrollTop } = useScrollTo(); const { getScrollTo, scrollTop } = useScrollTo();
const dispatch = useDispatch(); const dispatch = useDispatch();
const paenls = useSelector((state) => state.panels.panels[1]?.panelInfo); const paenls = useSelector((state) => state.panels.panels[1]?.panelInfo);
const youmaylikeInfos = useSelector((state) => state.main.youmaylikeInfos);
const scrollTopJob = useRef(new Job((func) => func(), 0)); const scrollTopJob = useRef(new Job((func) => func(), 0));
const [height, setHeight] = useState(); const [height, setHeight] = useState();
const gridStyle = useMemo(() => ({ height: `${height}px` }), [height]); const gridStyle = useMemo(() => ({ height: `${height}px` }), [height]);
// ShopNow + YouMayLike 통합 아이템 (v2이고 shopNow < 3일 때만)
const combinedItems = useMemo(() => {
if (!shopNowInfo) return [];
// 기본: ShopNow 아이템
let items = shopNowInfo.map((item) => ({
...item,
_type: 'shopnow',
}));
// v2 + ShopNow < 3 + YouMayLike 데이터 존재 시 통합
if (version === 2 && shopNowInfo.length < 3 && youmaylikeInfos && youmaylikeInfos.length > 0) {
items = items.concat(
youmaylikeInfos.map((item) => ({
...item,
_type: 'youmaylike',
}))
);
}
return items;
}, [shopNowInfo, youmaylikeInfos, version]);
// 각 상품별 가격 정보를 미리 계산 // 각 상품별 가격 정보를 미리 계산
const priceInfoMap = useMemo(() => { const priceInfoMap = useMemo(() => {
if (!shopNowInfo) return {}; if (!shopNowInfo) return {};
@@ -90,7 +90,7 @@ export default function ShopNowContents({
useEffect(() => { useEffect(() => {
return () => { return () => {
const gridListId = "playVideoShopNowBox"; const gridListId = 'playVideoShopNowBox';
const girdList = getContainerNode(gridListId); const girdList = getContainerNode(gridListId);
if (girdList) setContainerLastFocusedElement(null, [gridListId]); if (girdList) setContainerLastFocusedElement(null, [gridListId]);
@@ -129,6 +129,59 @@ export default function ShopNowContents({
const renderItem = useCallback( const renderItem = useCallback(
({ index, ...rest }) => { ({ index, ...rest }) => {
const item = combinedItems[index];
// ===== YouMayLike 아이템 처리 =====
if (item._type === 'youmaylike') {
const { imgUrl, patnrId, prdtId, prdtNm, priceInfo, offerInfo } = item;
// YouMayLike 시작 지점 여부 (구분선 표시)
const isYouMayLikeStart = shopNowInfo && index === shopNowInfo.length;
const handleItemClick = () => {
dispatch(
pushPanel({
name: panel_names.DETAIL_PANEL,
panelInfo: {
showNm: playListInfo?.showNm,
showId: playListInfo?.showId,
liveFlag: playListInfo?.liveFlag,
thumbnailUrl: playListInfo?.thumbnailUrl,
patnrId,
prdtId,
launchedFromPlayer: true,
},
})
);
};
return (
<>
{isYouMayLikeStart && <div className={css.youMayLikeDivider} />}
<TItemCard
{...rest}
key={prdtId}
imageAlt={prdtId}
imageSource={imgUrl}
priceInfo={priceInfo}
offerInfo={offerInfo}
productName={prdtNm}
productId={prdtId}
onClick={handleItemClick}
onFocus={() => {
if (handleItemFocus) {
handleItemFocus(LOG_MENU.FULL_YOU_MAY_LIKE);
}
}}
spotlightId={`you-may-like-item-${index}`}
type={TYPES.horizontal}
version={version}
/>
</>
);
}
// ===== ShopNow 아이템 처리 (기존 로직) =====
const { const {
imgUrls, imgUrls,
patnrId, patnrId,
@@ -140,11 +193,10 @@ export default function ShopNowContents({
patncNm, patncNm,
brndNm, brndNm,
catNm, catNm,
} = shopNowInfo[index]; } = item;
// 미리 계산된 가격 정보를 사용 // 미리 계산된 가격 정보를 사용
const { originalPrice, discountedPrice, discountRate } = const { originalPrice, discountedPrice, discountRate } = priceInfoMap[index] || {};
priceInfoMap[index] || {};
const handleItemClick = () => { const handleItemClick = () => {
const params = { const params = {
@@ -173,7 +225,7 @@ export default function ShopNowContents({
showId: playListInfo?.showId, showId: playListInfo?.showId,
liveFlag: playListInfo?.liveFlag, liveFlag: playListInfo?.liveFlag,
thumbnailUrl: playListInfo?.thumbnailUrl, thumbnailUrl: playListInfo?.thumbnailUrl,
liveReqFlag: panelInfo?.shptmBanrTpNm === "LIVE" && "Y", liveReqFlag: panelInfo?.shptmBanrTpNm === 'LIVE' && 'Y',
patnrId, patnrId,
prdtId, prdtId,
launchedFromPlayer: true, launchedFromPlayer: true,
@@ -202,7 +254,7 @@ export default function ShopNowContents({
// v2에서 첫 번째 아이템일 때 위로 가면 Close 버튼으로 // v2에서 첫 번째 아이템일 때 위로 가면 Close 버튼으로
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
Spotlight.focus("shownow_close_button"); Spotlight.focus('shownow_close_button');
} }
: undefined : undefined
} }
@@ -212,7 +264,7 @@ export default function ShopNowContents({
); );
}, },
[ [
shopNowInfo, combinedItems,
videoVerticalVisible, videoVerticalVisible,
panelInfo?.shptmBanrTpNm, panelInfo?.shptmBanrTpNm,
priceInfoMap, priceInfoMap,
@@ -221,25 +273,25 @@ export default function ShopNowContents({
playListInfo, playListInfo,
dispatch, dispatch,
version, version,
handleItemFocus,
handleFocus,
] ]
); );
return ( return (
<> <>
<Container className={css.container}> <Container className={css.container}>
{shopNowInfo && shopNowInfo.length > 0 ? ( {combinedItems && combinedItems.length > 0 ? (
<TVirtualGridList <TVirtualGridList
style={version === 2 ? undefined : gridStyle} style={version === 2 ? undefined : gridStyle}
cbScrollTo={getScrollTo} cbScrollTo={getScrollTo}
dataSize={shopNowInfo.length} dataSize={combinedItems.length}
direction={direction} direction={direction}
renderItem={renderItem} renderItem={renderItem}
itemWidth={version === 2 ? 310 : videoVerticalVisible ? 540 : 600} itemWidth={version === 2 ? 310 : videoVerticalVisible ? 540 : 600}
itemHeight={version === 2 ? 445 : 236} itemHeight={version === 2 ? 445 : 236}
spacing={version === 2 ? 30 : 12} spacing={version === 2 ? 30 : 12}
className={ className={videoVerticalVisible ? css.verticalItemList : css.itemList}
videoVerticalVisible ? css.verticalItemList : css.itemList
}
noScrollByWheel={false} noScrollByWheel={false}
spotlightId="playVideoShopNowBox" spotlightId="playVideoShopNowBox"
/> />

View File

@@ -51,3 +51,12 @@
} }
} }
} }
// YouMayLike 시작 지점 구분선
.youMayLikeDivider {
width: 2px !important;
height: 445px;
background: rgba(234, 234, 234, 0.3);
margin-right: 15px;
flex-shrink: 0;
}

View File

@@ -12,8 +12,11 @@
border-top: 1px solid rgba(234, 234, 234, 0.8); border-top: 1px solid rgba(234, 234, 234, 0.8);
overflow: hidden; overflow: hidden;
.flex(@display: flex, @justifyCenter: flex-start, @alignCenter: flex-start, @direction: column); .flex(@display: flex, @justifyCenter: flex-start, @alignCenter: flex-start, @direction: column);
gap: 40px;
z-index: 5; z-index: 5;
> * + * {
margin-top: 40px;
}
} }
.header { .header {
@@ -23,7 +26,10 @@
overflow: hidden; overflow: hidden;
border-radius: 100px; border-radius: 100px;
.flex(@display: flex, @justifyCenter: flex-start, @alignCenter: center); .flex(@display: flex, @justifyCenter: flex-start, @alignCenter: center);
gap: 15px;
> * + * {
margin-left: 15px;
}
} }
.iconWrapper { .iconWrapper {
@@ -51,11 +57,14 @@
.productList { .productList {
align-self: stretch; align-self: stretch;
.flex(@display: flex, @justifyCenter: flex-start, @alignCenter: flex-start); .flex(@display: flex, @justifyCenter: flex-start, @alignCenter: flex-start);
gap: 30px;
overflow-x: auto; overflow-x: auto;
overflow-y: hidden; overflow-y: hidden;
> * + * { > * {
margin-left: 0; margin-right: 30px;
&:last-child {
margin-right: 0;
}
} }
} }

View File

@@ -8,10 +8,13 @@
border-radius: 12px; border-radius: 12px;
border: 1px solid transparent; border: 1px solid transparent;
.flex(@display: flex, @justifyCenter: flex-start, @alignCenter: flex-start, @direction: column); .flex(@display: flex, @justifyCenter: flex-start, @alignCenter: flex-start, @direction: column);
gap: 15px;
flex-shrink: 0; flex-shrink: 0;
transition: all 0.3s ease; transition: all 0.3s ease;
> * + * {
margin-top: 15px;
}
&:focus { &:focus {
border-color: @PRIMARY_COLOR_RED; border-color: @PRIMARY_COLOR_RED;
outline: 4px @PRIMARY_COLOR_RED solid; outline: 4px @PRIMARY_COLOR_RED solid;
@@ -33,7 +36,10 @@
.productInfo { .productInfo {
align-self: stretch; align-self: stretch;
.flex(@display: flex, @justifyCenter: center, @alignCenter: flex-start, @direction: column); .flex(@display: flex, @justifyCenter: center, @alignCenter: flex-start, @direction: column);
gap: 15px;
> * + * {
margin-top: 15px;
}
} }
.productName { .productName {
@@ -49,13 +55,19 @@
.priceWrapper { .priceWrapper {
align-self: stretch; align-self: stretch;
.flex(@display: flex, @justifyCenter: flex-start, @alignCenter: flex-start); .flex(@display: flex, @justifyCenter: flex-start, @alignCenter: flex-start);
gap: 10px;
> * + * {
margin-left: 10px;
}
} }
.priceContainer { .priceContainer {
padding: 4px 0; padding: 4px 0;
.flex(@display: flex, @justifyCenter: flex-start, @alignCenter: center); .flex(@display: flex, @justifyCenter: flex-start, @alignCenter: center);
gap: 11px;
> * + * {
margin-left: 11px;
}
} }
.salePrice { .salePrice {

View File

@@ -1,35 +1,26 @@
import React, { import React, { useCallback, useEffect } from 'react';
useCallback,
useEffect,
} from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { useSelector } from 'react-redux';
import Spotlight from '@enact/spotlight'; import Spotlight from '@enact/spotlight';
import SpotlightContainerDecorator import SpotlightContainerDecorator from '@enact/spotlight/SpotlightContainerDecorator';
from '@enact/spotlight/SpotlightContainerDecorator';
import Spottable from '@enact/spotlight/Spottable'; import Spottable from '@enact/spotlight/Spottable';
// import icon_arrow_right from '../../../../../assets/images/icons'; // import icon_arrow_right from '../../../../../assets/images/icons';
import icon_arrow_dwon import icon_arrow_dwon from '../../../../../assets/images/player/icon_tabcontainer_arrow_down.png';
from '../../../../../assets/images/player/icon_tabcontainer_arrow_down.png'; import icon_shop_now from '../../../../../assets/images/player/icon_tabcontainer_shopnow.png';
import icon_shop_now
from '../../../../../assets/images/player/icon_tabcontainer_shopnow.png';
import { LOG_MENU } from '../../../../utils/Config'; import { LOG_MENU } from '../../../../utils/Config';
import { $L } from '../../../../utils/helperMethods'; import { $L } from '../../../../utils/helperMethods';
import { SpotlightIds } from '../../../../utils/SpotlightIds'; import { SpotlightIds } from '../../../../utils/SpotlightIds';
import LiveChannelContents from '../TabContents/LiveChannelContents'; import LiveChannelContents from '../TabContents/LiveChannelContents';
import ShopNowContents from '../TabContents/ShopNowContents'; import ShopNowContents from '../TabContents/ShopNowContents';
import YouMayLikeContents from '../TabContents/YouMayLikeContents';
import ShopNowButton from './ShopNowButton'; import ShopNowButton from './ShopNowButton';
import css from './TabContainer.v2.module.less'; import css from './TabContainer.v2.module.less';
const Container = SpotlightContainerDecorator( const Container = SpotlightContainerDecorator({ enterTo: 'last-focused' }, 'div');
{ enterTo: "last-focused" },
"div"
);
const SpottableDiv = Spottable("div"); const SpottableDiv = Spottable('div');
export default function TabContainerV2({ export default function TabContainerV2({
panelInfo, panelInfo,
@@ -49,11 +40,11 @@ export default function TabContainerV2({
onTabClose, // 탭 닫기 콜백 함수 onTabClose, // 탭 닫기 콜백 함수
tabVisible, tabVisible,
}) { }) {
const youmaylikeInfos = useSelector((state) => state.main.youmaylikeInfos);
const tabList = [ const tabList = [
$L("SHOP NOW"), $L('SHOP NOW'),
panelInfo?.shptmBanrTpNm === "LIVE" panelInfo?.shptmBanrTpNm === 'LIVE' ? $L('LIVE CHANNEL') : $L('FEATURED SHOWS'),
? $L("LIVE CHANNEL")
: $L("FEATURED SHOWS"),
]; ];
useEffect(() => { useEffect(() => {
@@ -64,10 +55,8 @@ export default function TabContainerV2({
} }
if (tabIndex === 1) { if (tabIndex === 1) {
const isLive = panelInfo?.shptmBanrTpNm === "LIVE"; const isLive = panelInfo?.shptmBanrTpNm === 'LIVE';
nowMenu = isLive nowMenu = isLive ? LOG_MENU.FULL_LIVE_CHANNELS : LOG_MENU.FULL_FEATURED_SHOWS;
? LOG_MENU.FULL_LIVE_CHANNELS
: LOG_MENU.FULL_FEATURED_SHOWS;
} }
if (nowMenu) { if (nowMenu) {
@@ -89,7 +78,7 @@ export default function TabContainerV2({
if (videoVerticalVisible) { if (videoVerticalVisible) {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
Spotlight.focus("spotlightId-video-contaienr"); Spotlight.focus('spotlightId-video-contaienr');
} }
}, },
[videoVerticalVisible] [videoVerticalVisible]
@@ -120,7 +109,7 @@ export default function TabContainerV2({
useEffect(() => { useEffect(() => {
if (tabIndex === 2) { if (tabIndex === 2) {
setTimeout(() => { setTimeout(() => {
Spotlight.focus("below-tab-shop-now-button"); Spotlight.focus('below-tab-shop-now-button');
}, 100); }, 100);
} }
}, [tabIndex]); }, [tabIndex]);
@@ -136,45 +125,53 @@ export default function TabContainerV2({
> >
{tabVisible && tabIndex === 0 && ( {tabVisible && tabIndex === 0 && (
<> <>
<div className={css.shopNowHeader}> <div className={css.shopNowHeaderContainer}>
<SpottableDiv <div className={css.shopNowHeader}>
className={css.shopNowHeaderLeft} <SpottableDiv
spotlightId="shownow_close_button" className={css.shopNowHeaderLeft}
onClick={handleCloseButtonClick} spotlightId="shownow_close_button"
onSpotlightUp={handleSpotlightUpToBackButton} onClick={handleCloseButtonClick}
onSpotlightDown={(e) => { onSpotlightUp={handleSpotlightUpToBackButton}
// 첫 번째 ShopNow 아이템으로 포커스 이동 onSpotlightDown={(e) => {
e.stopPropagation(); // 첫 번째 ShopNow 아이템으로 포커스 이동
e.preventDefault(); e.stopPropagation();
Spotlight.focus("shop-now-item-0"); e.preventDefault();
}} Spotlight.focus('shop-now-item-0');
> }}
<div className={css.shopNowIconWrapper}> >
<img <div className={css.shopNowIconWrapper}>
src={icon_shop_now} <img src={icon_shop_now} alt="shop now icon" className={css.shopNowIcon} />
alt="shop now icon" </div>
className={css.shopNowIcon} <div className={css.shopNowHeaderText}>SHOP NOW</div>
/> <div className={css.arrowIcon}>
</div> <img src={icon_arrow_dwon} alt="arrow down" />
<div className={css.shopNowHeaderText}>SHOP NOW</div> </div>
<div className={css.arrowIcon}> </SpottableDiv>
<img src={icon_arrow_dwon} alt="arrow down" /> {/* <SpottableDiv
</div> className={css.closeButton}
</SpottableDiv> spotlightId="below-tab-close-button"
{/* <SpottableDiv onClick={handleCloseButtonClick}
className={css.closeButton} onSpotlightUp={handleSpotlightUpToBackButton}
spotlightId="below-tab-close-button" onSpotlightDown={(e) => {
onClick={handleCloseButtonClick} // 첫 번째 ShopNow 아이템으로 포커스 이동
onSpotlightUp={handleSpotlightUpToBackButton} e.stopPropagation();
onSpotlightDown={(e) => { e.preventDefault();
// 첫 번째 ShopNow 아이템으로 포커스 이동 Spotlight.focus("shop-now-item-0");
e.stopPropagation(); }}
e.preventDefault(); >
Spotlight.focus("shop-now-item-0"); ×
}} </SpottableDiv> */}
> </div>
×
</SpottableDiv> */} {/* YouMayAlso Like 헤더 (ShopNow 아이템 < 3 && YouMayLike 데이터 존재) */}
{shopNowInfo &&
shopNowInfo.length < 3 &&
youmaylikeInfos &&
youmaylikeInfos.length > 0 && (
<div className={css.youMayAlsoLikeHeader}>
<div className={css.youMayAlsoLikeText}>You may also like</div>
</div>
)}
</div> </div>
<ShopNowContents <ShopNowContents
tabTitle={tabList} tabTitle={tabList}
@@ -187,15 +184,6 @@ export default function TabContainerV2({
version={2} version={2}
direction="horizontal" direction="horizontal"
/> />
{shopNowInfo && shopNowInfo.length < 3 && (
<YouMayLikeContents
shopNowInfo={shopNowInfo}
handleItemFocus={_handleItemFocus}
playListInfo={playListInfo && playListInfo[selectedIndex]}
version={2}
direction="horizontal"
/>
)}
</> </>
)} )}
@@ -208,7 +196,7 @@ export default function TabContainerV2({
onSpotlightUp={handleSpotlightUpToBackButton} onSpotlightUp={handleSpotlightUpToBackButton}
onSpotlightDown={(e) => { onSpotlightDown={(e) => {
// 첫 번째 PlayerItem으로 포커스 이동 // 첫 번째 PlayerItem으로 포커스 이동
Spotlight.focus("tabChannel-video-0"); Spotlight.focus('tabChannel-video-0');
}} }}
> >
<span className={css.buttonText}>LIVE CHANNEL</span> <span className={css.buttonText}>LIVE CHANNEL</span>
@@ -217,7 +205,7 @@ export default function TabContainerV2({
</div> </div>
</SpottableDiv> </SpottableDiv>
{panelInfo?.shptmBanrTpNm === "LIVE" && playListInfo && ( {panelInfo?.shptmBanrTpNm === 'LIVE' && playListInfo && (
<LiveChannelContents <LiveChannelContents
tabTitle={tabList} tabTitle={tabList}
selectedIndex={selectedIndex} selectedIndex={selectedIndex}
@@ -236,9 +224,7 @@ export default function TabContainerV2({
</> </>
)} )}
{tabVisible && tabIndex === 2 && ( {tabVisible && tabIndex === 2 && <ShopNowButton onClick={onShopNowButtonClick} />}
<ShopNowButton onClick={onShopNowButtonClick} />
)}
</Container> </Container>
); );
} }

View File

@@ -89,14 +89,22 @@
} }
} }
// ShopNow 헤더 컨테이너 (ShopNow + YouMayAlsoLike 헤더를 같은 라인에 배치)
.shopNowHeaderContainer {
display: flex;
align-items: center;
width: 100%;
}
// SHOP NOW 헤더 스타일 (ShopNowContainer 참고) // SHOP NOW 헤더 스타일 (ShopNowContainer 참고)
.shopNowHeader { .shopNowHeader {
width: 100%; width: auto;
height: 70px; height: 70px;
padding: 20px 0; padding: 20px 0;
overflow: hidden; overflow: hidden;
border-radius: 100px; border-radius: 100px;
.flex(@display: flex, @justifyCenter: space-between, @alignCenter: center); .flex(@display: flex, @justifyCenter: space-between, @alignCenter: center);
flex-shrink: 0;
} }
.shopNowIconWrapper { .shopNowIconWrapper {
@@ -239,6 +247,31 @@
} }
} }
} }
// YOU MAY ALSO LIKE 헤더 스타일
.youMayAlsoLikeHeader {
margin-left: 90px;
height: 100%;
display: flex;
align-items: center;
justify-content: flex-start;
padding: 20px 0;
overflow: hidden;
border-radius: 100px;
flex-shrink: 0;
}
.youMayAlsoLikeText {
margin-right: 15px;
color: #EAEAEA;
font-size: 24px;
font-family: @baseFont;
font-weight: 700;
line-height: 31px;
word-wrap: break-word;
white-space: nowrap;
}
/* 애니메이션 정의 */ /* 애니메이션 정의 */
@keyframes slideInFromRight { @keyframes slideInFromRight {
from { from {