Merge branch 'develop_si' into feature/si_log

This commit is contained in:
opacity@t-win.kr
2025-12-05 10:43:14 +09:00
6 changed files with 76 additions and 40 deletions

View File

@@ -6,7 +6,7 @@
padding-top: 60px; padding-top: 60px;
} }
.emptyBox { .emptyBox {
width: 1320px; width: 1200px;
height: 288px; height: 288px;
text-align: center; text-align: center;
display: flex; display: flex;
@@ -39,5 +39,6 @@
} }
.bestSeller { .bestSeller {
margin-top: 70px; margin-top: 70px;
width: 1320px; width: 1200px;
padding-right:10px;
} }

View File

@@ -341,24 +341,24 @@ const CartSidebar = ({ cartInfo }) => {
<div className={css.summarySection}> <div className={css.summarySection}>
<div className={css.header}> <div className={css.header}>
<div className={css.title}>Subtotal</div> <div className={css.title}>Subtotal</div>
<span className={css.itemCount}>{itemCount} Items</span> <span className={css.itemCount}>{userNumber ? itemCount : 0} Items</span>
</div> </div>
<div className={css.borderLine} /> <div className={css.borderLine} />
<div className={css.priceList}> <div className={css.priceList}>
<div className={css.priceItem}> <div className={css.priceItem}>
<span className={css.label}>Subtotal</span> <span className={css.label}>Subtotal</span>
<span className={css.value}>{formatPrice(subtotal)}</span> <span className={css.value}>{userNumber ? formatPrice(subtotal) : 0}</span>
</div> </div>
<div className={css.priceItem}> <div className={css.priceItem}>
<span className={css.label}>Option</span> <span className={css.label}>Option</span>
<span className={css.value}> <span className={css.value}>
{formatPrice(optionTotal)} {userNumber ? formatPrice(optionTotal) : 0}
</span> </span>
</div> </div>
<div className={css.priceItem}> <div className={css.priceItem}>
<span className={css.label}>S&H</span> <span className={css.label}>S&H</span>
<span className={css.value}> <span className={css.value}>
{formatPrice(shippingHandling)} {userNumber ? formatPrice(shippingHandling) : 0}
</span> </span>
</div> </div>
</div> </div>
@@ -369,7 +369,7 @@ const CartSidebar = ({ cartInfo }) => {
<span className={css.totalLabelSub}>(Before Tax)</span> <span className={css.totalLabelSub}>(Before Tax)</span>
</span> </span>
<span className={css.totalValue}> <span className={css.totalValue}>
{formatPrice(orderTotalBeforeTax)} {userNumber ? formatPrice(orderTotalBeforeTax) : 0}
</span> </span>
</div> </div>
</div> </div>
@@ -391,7 +391,7 @@ const CartSidebar = ({ cartInfo }) => {
className={css.checkoutButton} className={css.checkoutButton}
spotlightId="cart-checkout-button" spotlightId="cart-checkout-button"
onClick={handleCheckoutClick} onClick={handleCheckoutClick}
disabled={itemsToCalculate.length === 0} disabled={checkedItems.length === 0 || (itemsToCalculate.length === 0 || !userNumber)}
> >
Checkout Checkout
</TButton> </TButton>

View File

@@ -115,11 +115,16 @@ export default function RollingUnit({
const previousTimeRef = useRef(); const previousTimeRef = useRef();
const arrRef = useRef([]); const arrRef = useRef([]);
const bannerDataRef = useRef(bannerData); const bannerDataRef = useRef(bannerData);
const rollingDataRef = useRef(rollingData); const filteredRollingDataRef = useRef(filteredRollingData);
// filteredRollingDataRef 업데이트
useEffect(() => {
filteredRollingDataRef.current = filteredRollingData;
}, [filteredRollingData]);
const topContentsLogInfo = useMemo(() => { const topContentsLogInfo = useMemo(() => {
if (rollingDataRef.current) { if (filteredRollingDataRef.current && filteredRollingDataRef.current.length > 0) {
const currentRollingData = rollingDataRef.current[startIndex]; const currentRollingData = filteredRollingDataRef.current[startIndex];
let contId, contNm; let contId, contNm;
@@ -172,9 +177,10 @@ export default function RollingUnit({
return {}; return {};
}, [shptmTmplCd, startIndex]); }, [shptmTmplCd, startIndex]);
const sendBannerLog = useCallback( const sendBannerLog = useCallback(
(bannerClick) => { (bannerClick) => {
const data = rollingDataRef.current[startIndex]; const data = filteredRollingDataRef.current[startIndex];
const newParams = const newParams =
bannerData.banrLctnNo === '2' bannerData.banrLctnNo === '2'
? { ? {
@@ -183,7 +189,7 @@ export default function RollingUnit({
: { : {
bannerType: 'Vertical', bannerType: 'Vertical',
}; };
if (rollingDataRef.current && nowMenu === LOG_MENU.HOME_TOP) { if (filteredRollingDataRef.current && nowMenu === LOG_MENU.HOME_TOP) {
const logParams = { const logParams = {
contextName: LOG_CONTEXT_NAME.HOME, contextName: LOG_CONTEXT_NAME.HOME,
messageId: bannerClick ? LOG_MESSAGE_ID.BANNER_CLICK : LOG_MESSAGE_ID.BANNER, messageId: bannerClick ? LOG_MESSAGE_ID.BANNER_CLICK : LOG_MESSAGE_ID.BANNER,
@@ -305,12 +311,13 @@ export default function RollingUnit({
const categoryData = useMemo(() => { const categoryData = useMemo(() => {
if ( if (
Object.keys(rollingData[startIndex]).length > 0 && filteredRollingData.length > 0 &&
rollingData[startIndex].shptmLnkTpCd === LINK_TYPES.CATEGORY Object.keys(filteredRollingData[startIndex]).length > 0 &&
filteredRollingData[startIndex].shptmLnkTpCd === LINK_TYPES.CATEGORY
) { ) {
if (homeCategory && homeCategory.length > 0) { if (homeCategory && homeCategory.length > 0) {
const foundCategory = homeCategory.find( const foundCategory = homeCategory.find(
(data) => data.lgCatCd === rollingData[startIndex].lgCatCd (data) => data.lgCatCd === filteredRollingData[startIndex].lgCatCd
); );
if (foundCategory) { if (foundCategory) {
return { return {
@@ -321,10 +328,10 @@ export default function RollingUnit({
} }
} }
return {}; return {};
}, [homeCategory, rollingData, startIndex]); }, [homeCategory, filteredRollingData, startIndex]);
const { originalPrice, discountedPrice, discountRate, offerInfo } = const { originalPrice, discountedPrice, discountRate, offerInfo } =
usePriceInfo(rollingData[startIndex].priceInfo) || {}; usePriceInfo(filteredRollingData.length > 0 ? filteredRollingData[startIndex].priceInfo : {}) || {};
const handlePushPanel = useCallback( const handlePushPanel = useCallback(
(name, panelInfo) => { (name, panelInfo) => {
@@ -350,10 +357,16 @@ export default function RollingUnit({
); );
const imageBannerClick = useCallback(() => { const imageBannerClick = useCallback(() => {
// 필터링된 데이터가 비어있으면 return
if (!filteredRollingData || filteredRollingData.length === 0) {
return;
}
if (bannerId) { if (bannerId) {
dispatch(setBannerIndex(bannerId, startIndex)); dispatch(setBannerIndex(bannerId, startIndex));
} }
const currentData = rollingData[startIndex];
const currentData = filteredRollingData[startIndex];
const linkType = currentData.shptmLnkTpCd; const linkType = currentData.shptmLnkTpCd;
const bannerType = currentData.shptmBanrTpNm; const bannerType = currentData.shptmBanrTpNm;
@@ -432,7 +445,7 @@ export default function RollingUnit({
}) })
); );
}, [ }, [
rollingData, filteredRollingData,
startIndex, startIndex,
bannerId, bannerId,
dispatch, dispatch,
@@ -443,6 +456,11 @@ export default function RollingUnit({
]); ]);
const videoClick = useCallback(() => { const videoClick = useCallback(() => {
// 필터링된 데이터가 비어있으면 return
if (!filteredRollingData || filteredRollingData.length === 0) {
return;
}
const lastFocusedTargetId = getContainerId(Spotlight.getCurrent()); const lastFocusedTargetId = getContainerId(Spotlight.getCurrent());
const currentSpot = Spotlight.getCurrent(); const currentSpot = Spotlight.getCurrent();
@@ -463,7 +481,7 @@ export default function RollingUnit({
dispatch(setBannerIndex(bannerId, startIndex)); dispatch(setBannerIndex(bannerId, startIndex));
} }
const currentData = rollingData[startIndex]; const currentData = filteredRollingData[startIndex];
handleStartVideoPlayer({ handleStartVideoPlayer({
showUrl: currentData.showUrl, showUrl: currentData.showUrl,
@@ -485,7 +503,7 @@ export default function RollingUnit({
logTpNo: LOG_TP_NO.TOP_CONTENTS.CLICK, logTpNo: LOG_TP_NO.TOP_CONTENTS.CLICK,
}) })
); );
}, [rollingData, startIndex, bannerId, dispatch, handleStartVideoPlayer, topContentsLogInfo]); }, [filteredRollingData, startIndex, bannerId, dispatch, handleStartVideoPlayer, topContentsLogInfo]);
// 10초 롤링 // 10초 롤링
useEffect(() => { useEffect(() => {
@@ -537,7 +555,7 @@ export default function RollingUnit({
useEffect(() => { useEffect(() => {
sendBannerLog(); sendBannerLog();
}, [rollingDataRef, nowMenu, startIndex]); }, [filteredRollingDataRef, nowMenu, startIndex]);
useEffect(() => { useEffect(() => {
if (nowMenu !== LOG_MENU.HOME_TOP) { if (nowMenu !== LOG_MENU.HOME_TOP) {
@@ -551,7 +569,7 @@ export default function RollingUnit({
spotlightId={`container-${spotlightId}`} spotlightId={`container-${spotlightId}`}
onFocus={shelfFocus} onFocus={shelfFocus}
> >
{filteredRollingData !== 1 ? ( {filteredRollingData.length !== 1 ? (
<SpottableComponent <SpottableComponent
className={classNames(css.arrow, css.leftBtn)} className={classNames(css.arrow, css.leftBtn)}
onClick={handlePrev} onClick={handlePrev}
@@ -564,7 +582,7 @@ export default function RollingUnit({
/> />
) : null} ) : null}
{filteredRollingData && filteredRollingData[startIndex].shptmBanrTpNm === 'Image Banner' ? ( {filteredRollingData && filteredRollingData.length > 0 && filteredRollingData[startIndex].shptmBanrTpNm === 'Image Banner' ? (
<SpottableComponent <SpottableComponent
className={classNames(css.itemBox, isHorizontal && css.isHorizontal)} className={classNames(css.itemBox, isHorizontal && css.isHorizontal)}
onClick={imageBannerClick} onClick={imageBannerClick}
@@ -582,7 +600,7 @@ export default function RollingUnit({
<img src={filteredRollingData[startIndex].tmnlImgPath} /> <img src={filteredRollingData[startIndex].tmnlImgPath} />
</div> </div>
</SpottableComponent> </SpottableComponent>
) : filteredRollingData[startIndex].shptmBanrTpNm === 'LIVE' ? ( ) : filteredRollingData && filteredRollingData.length > 0 && filteredRollingData[startIndex].shptmBanrTpNm === 'LIVE' ? (
<SpottableComponent <SpottableComponent
className={classNames(css.itemBox, isHorizontal && css.isHorizontal)} className={classNames(css.itemBox, isHorizontal && css.isHorizontal)}
onClick={videoClick} onClick={videoClick}
@@ -634,7 +652,7 @@ export default function RollingUnit({
/> />
</p> </p>
</SpottableComponent> </SpottableComponent>
) : filteredRollingData[startIndex].shptmBanrTpNm === 'VOD' ? ( ) : filteredRollingData && filteredRollingData.length > 0 && filteredRollingData[startIndex].shptmBanrTpNm === 'VOD' ? (
<SpottableComponent <SpottableComponent
className={classNames(css.itemBox, isHorizontal && css.isHorizontal)} className={classNames(css.itemBox, isHorizontal && css.isHorizontal)}
onClick={videoClick} onClick={videoClick}
@@ -682,7 +700,7 @@ export default function RollingUnit({
)} )}
</div> </div>
</SpottableComponent> </SpottableComponent>
) : filteredRollingData[startIndex].shptmBanrTpNm === "Today's Deals" ? ( ) : filteredRollingData && filteredRollingData.length > 0 && filteredRollingData[startIndex].shptmBanrTpNm === "Today's Deals" ? (
<SpottableComponent <SpottableComponent
className={classNames( className={classNames(
css.itemBox, css.itemBox,
@@ -738,7 +756,7 @@ export default function RollingUnit({
</SpottableComponent> </SpottableComponent>
) : null} ) : null}
{filteredRollingData !== 1 ? ( {filteredRollingData.length !== 1 ? (
<SpottableComponent <SpottableComponent
className={classNames(css.arrow, css.rightBtn)} className={classNames(css.arrow, css.rightBtn)}
onClick={handleNext} onClick={handleNext}

View File

@@ -1,14 +1,24 @@
import React, { useCallback, useEffect, useMemo, useRef } from 'react'; import React, {
useCallback,
useEffect,
useMemo,
useRef,
} from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { useDispatch, useSelector } from 'react-redux'; import {
useDispatch,
useSelector,
} from 'react-redux';
import Spotlight from '@enact/spotlight'; import Spotlight from '@enact/spotlight';
import SpotlightContainerDecorator from '@enact/spotlight/SpotlightContainerDecorator'; import SpotlightContainerDecorator
from '@enact/spotlight/SpotlightContainerDecorator';
import Spottable from '@enact/spotlight/Spottable'; import Spottable from '@enact/spotlight/Spottable';
import Marquee from '@enact/ui/Marquee'; import Marquee from '@enact/ui/Marquee';
import defaultLogoImg from '../../../../assets/images/ic-tab-partners-default@3x.png'; import defaultLogoImg
from '../../../../assets/images/ic-tab-partners-default@3x.png';
import { setShowPopup } from '../../../actions/commonActions'; import { setShowPopup } from '../../../actions/commonActions';
import CustomImage from '../../../components/CustomImage/CustomImage'; import CustomImage from '../../../components/CustomImage/CustomImage';
import { ACTIVE_POPUP } from '../../../utils/Config'; import { ACTIVE_POPUP } from '../../../utils/Config';
@@ -388,7 +398,7 @@ function PlayerOverlayContents({
e.preventDefault(); e.preventDefault();
// tabIndexV2가 2일 때만 ShopNowButton으로 포커스 // tabIndexV2가 2일 때만 ShopNowButton으로 포커스
if (tabContainerVersion === 2 && tabIndexV2 === 2) { if (tabContainerVersion === 2 && tabIndexV2 === 2) {
Spotlight.focus('below-tab-shop-now-button'); Spotlight.focus('live-channel-next-button');
} }
}} }}
aria-label="Caption" aria-label="Caption"

View File

@@ -1,11 +1,16 @@
import React from 'react'; import React from 'react';
import { compose } from 'ramda/src/compose';
import Spotlight from '@enact/spotlight'; import Spotlight from '@enact/spotlight';
import Spottable from '@enact/spotlight/Spottable'; import Spottable from '@enact/spotlight/Spottable';
import { Marquee, MarqueeController } from '@enact/ui/Marquee'; import {
import { compose } from 'ramda/src/compose'; Marquee,
MarqueeController,
} from '@enact/ui/Marquee';
import icon_arrow_dwon from '../../../../../assets/images/player/icon_tabcontainer_arrow_down.png'; import icon_arrow_dwon
from '../../../../../assets/images/player/icon_tabcontainer_arrow_down.png';
import CustomImage from '../../../../components/CustomImage/CustomImage'; import CustomImage from '../../../../components/CustomImage/CustomImage';
import { SpotlightIds } from '../../../../utils/SpotlightIds'; import { SpotlightIds } from '../../../../utils/SpotlightIds';
import css from './LiveChannelNext.module.less'; import css from './LiveChannelNext.module.less';
@@ -18,14 +23,14 @@ export default function LiveChannelNext({
programName = 'Sandal Black...', programName = 'Sandal Black...',
backgroundColor = 'linear-gradient(180deg, #284998 0%, #06B0EE 100%)', backgroundColor = 'linear-gradient(180deg, #284998 0%, #06B0EE 100%)',
onClick, onClick,
onFocus,
spotlightId = 'live-channel-next-button', spotlightId = 'live-channel-next-button',
}) { }) {
const handleSpotlightUp = (e) => { const handleSpotlightUp = (e) => {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
Spotlight.focus(SpotlightIds.PLAYER_BACK_BUTTON); Spotlight.focus('player-subtitlebutton');
}; };
const handleSpotlightDown = (e) => { const handleSpotlightDown = (e) => {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
@@ -43,6 +48,7 @@ export default function LiveChannelNext({
<SpottableDiv <SpottableDiv
className={css.liveChannelButton} className={css.liveChannelButton}
onClick={onClick} onClick={onClick}
onFocus={onFocus}
spotlightId={spotlightId} spotlightId={spotlightId}
onSpotlightUp={handleSpotlightUp} onSpotlightUp={handleSpotlightUp}
onSpotlightDown={handleSpotlightDown} onSpotlightDown={handleSpotlightDown}

View File

@@ -50,7 +50,7 @@ export default function TabContainerV2({
onTabClose, // 탭 닫기 콜백 함수 onTabClose, // 탭 닫기 콜백 함수
tabVisible, tabVisible,
}) { }) {
const youmaylikeInfos = useSelector((state) => state.main.youmaylikeInfos); const youmaylikeInfos = useSelector((state) => state.main.youmaylikeInfos);
// 다음 재생 가능한 쇼 찾기 // 다음 재생 가능한 쇼 찾기
const findNextPlayableShow = useCallback((currentPlayList, currentIndex) => { const findNextPlayableShow = useCallback((currentPlayList, currentIndex) => {
@@ -337,6 +337,7 @@ export default function TabContainerV2({
} }
onClick={onLiveNext} onClick={onLiveNext}
spotlightId="live-channel-next-button" spotlightId="live-channel-next-button"
onFocus={onLiveNext}
/> />
<ShopNowButton onClick={onShopNowButtonClick} /> <ShopNowButton onClick={onShopNowButtonClick} />
</> </>