Files
shoptime/com.twin.app.shoptime/src/views/HomePanel/BestSeller/BestSeller.jsx
junghoon86.park c540378cb5 [foryou] 로그인, 비로그인시 노출 차이 수정
- 포유 아이콘 관련 처리부분 비로그인시 노출안되도록 처리.
 - 픽포유는 홈패널에서 노출로 처리.
2025-12-15 16:15:51 +09:00

314 lines
8.6 KiB
JavaScript

import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import Spotlight from '@enact/spotlight';
import { SpotlightContainerDecorator } from '@enact/spotlight/SpotlightContainerDecorator';
import Spottable from '@enact/spotlight/Spottable';
import {
navigateFromBestSeller,
pushPanel,
updatePanel,
} from '../../../actions/panelActions';
import { navigateToDetailFromHome } from '../../../actions/panelNavigationActions';
import SectionTitle from '../../../components/SectionTitle/SectionTitle';
import Tag from '../../../components/TItemCard/Tag';
import TItemCard from '../../../components/TItemCard/TItemCard';
import TItemCardNew from '../../../components/TItemCard/TItemCard.new';
import TScroller from '../../../components/TScroller/TScroller';
import useScrollReset from '../../../hooks/useScrollReset';
import useScrollTo from '../../../hooks/useScrollTo';
import {
LOG_CONTEXT_NAME,
LOG_MESSAGE_ID,
panel_names,
} from '../../../utils/Config';
import { $L, scaleW } from '../../../utils/helperMethods';
import { SpotlightIds } from '../../../utils/SpotlightIds';
import css from './BestSeller.module.less';
const SpottableComponent = Spottable('div');
const Container = SpotlightContainerDecorator(
{ enterTo: 'last-focused' },
'div'
);
const BestSeller = ({
order,
scrollTopBody,
spotlightId,
handleItemFocus,
handleShelfFocus,
shelfLocation,
shelfTitle,
}) => {
const { getScrollTo, scrollLeft } = useScrollTo();
const { handleScrollReset, handleStopScrolling } = useScrollReset(
scrollLeft,
true
);
const dispatch = useDispatch();
const { cursorVisible } = useSelector((state) => state.common.appStatus);
const bestSellerDatas = useSelector(
(state) => state.product.bestSellerData?.bestSeller
);
const bestSellerNewDatas = useSelector(
(state) => state.foryou?.recommendInfo?.recommendProduct
);
const { userNumber } = useSelector(
(state) => state.common.appStatus.loginUserData
);
const [drawChk, setDrawChk] = useState(false);
const [firstChk, setFirstChk] = useState(0);
const [bestInfos, setBestInfos] = useState(null);
const [bestItemNewData, setBestItemNewData] = useState([]);
useEffect(() => {
setBestInfos(
bestSellerNewDatas?.filter(
(item) => item.recommendTpCd === 'BESTSELLER'
) || [] // 기본값으로 빈 배열 설정
);
}, [bestSellerNewDatas]);
useEffect(() => {
if (userNumber) {
if (!bestInfos || bestInfos.length === 0) {
const baseData =
bestSellerDatas?.map((item) => ({
...item,
foryou: false,
})) || [];
setBestItemNewData(baseData);
return;
}
const recommendedData =
bestInfos[0].productInfos?.map((item) => ({
...item,
foryou: true,
})) || [];
const recommendedPrdtIds = new Set(
recommendedData.map((item) => item.prdtId)
);
const baseData =
bestSellerDatas?.map((item) => ({
...item,
foryou: recommendedPrdtIds.has(item.prdtId),
})) || [];
setBestItemNewData(baseData);
} else {
setBestItemNewData(bestSellerDatas);
}
}, [bestSellerDatas, bestInfos, userNumber]);
const orderStyle = useMemo(() => ({ order: order }), [order]);
useEffect(() => {
setDrawChk(true);
}, [bestSellerNewDatas]);
const handleCardClick = useCallback(
(patnrId, prdtId) => () => {
dispatch(
navigateFromBestSeller({
patnrId,
prdtId,
spotlightId,
})
);
},
[dispatch, spotlightId]
);
const handleMoreCardClick = useCallback(() => {
dispatch(
pushPanel({
name: panel_names.TRENDING_NOW_PANEL,
panelInfo: {
pageName: 'BS',
focusedContainerId: SpotlightIds.TRENDING_NOW_BEST_SELLER,
},
})
);
}, [dispatch]);
const handleBlur = useCallback(
(itemIndex) => () => {
if (itemIndex === 0) {
handleStopScrolling();
}
},
[handleStopScrolling]
);
const handleFocus = useCallback(
(itemIndex) => () => {
_handleItemFocus();
if (itemIndex === 0) {
handleScrollReset();
}
if (firstChk === 0 && itemIndex === 0) {
const c = Spotlight.getCurrent();
if (c) {
let cAriaLabel = c.getAttribute('aria-label');
cAriaLabel = 'Best Seller, Heading 1,' + cAriaLabel;
c.setAttribute('aria-label', cAriaLabel);
}
setFirstChk(1);
} else if (firstChk === 1 && itemIndex === 0) {
const c = Spotlight.getCurrent();
if (c) {
let cAriaLabel = c.getAttribute('aria-label');
if (cAriaLabel) {
const newcAriaLabel = cAriaLabel.replace(
'Best Seller, Heading 1,',
''
);
c.setAttribute('aria-label', newcAriaLabel);
}
}
} else {
return;
}
if (cursorVisible) {
return;
}
},
[cursorVisible, _handleItemFocus, handleScrollReset, scrollTopBody]
);
const handleScrollRight = (e) => {
const container = e.currentTarget?.parentNode;
const x = container.scrollWidth - container.clientWidth + 60;
setTimeout(() => {
scrollLeft({ x, animate: true });
});
};
const _handleItemFocus = useCallback(() => {
if (handleItemFocus) {
handleItemFocus();
}
}, [handleItemFocus]);
const _handleShelfFocus = useCallback(() => {
if (handleShelfFocus) {
handleShelfFocus();
}
}, [handleShelfFocus]);
return (
<Container
className={css.bestSellerWrap}
style={orderStyle}
spotlightId={spotlightId}
data-wheel-point={true}
onFocus={_handleShelfFocus}
>
<SectionTitle
title={$L('BEST SELLER')}
data-title-index="homeBestSellerTitle"
label="BEST SELLER"
/>
<TScroller
className={css.homeBestSeller}
direction="horizontal"
cbScrollTo={getScrollTo}
noScrollByWheel
>
{bestItemNewData &&
bestItemNewData.map(
(
{
prdtId,
imgUrl,
priceInfo,
prdtNm,
rankOrd,
patnrId,
offerInfo,
brndNm,
patncNm,
//catNm, 없음
foryou,
euEnrgLblInfos,
},
itemIndex
) => {
const rankText =
rankOrd === 1
? rankOrd + 'st'
: rankOrd === 2
? rankOrd + 'nd'
: rankOrd === 3
? rankOrd + 'rd'
: rankOrd + 'th';
return (
<TItemCardNew
key={'subItem' + itemIndex}
contextName={LOG_CONTEXT_NAME.HOME}
messageId={LOG_MESSAGE_ID.SHELF_CLICK}
order={itemIndex + 1}
shelfId={spotlightId}
shelfLocation={shelfLocation}
shelfTitle={shelfTitle}
patnerName={patncNm}
brandName={brndNm}
// catNm={catNm}
imageAlt={prdtId}
imageSource={imgUrl}
priceInfo={priceInfo}
productName={prdtNm}
isBestSeller={true}
productId={prdtId}
rank={rankOrd}
onFocus={handleFocus(itemIndex)}
onBlur={handleBlur(itemIndex)}
onClick={handleCardClick(patnrId, prdtId)}
offerInfo={offerInfo}
spotlightId={'bestsellerItem' + itemIndex}
firstLabel={rankText}
label={itemIndex * 1 + 1 + ' of ' + bestItemNewData.length}
lastLabel=" go to detail, button"
euEnrgLblInfos={euEnrgLblInfos}
>
{foryou === true && <Tag text={'For You'} />}
</TItemCardNew>
);
}
)}
{drawChk && (
<div className={css.addItem} onFocus={handleScrollRight}>
<SpottableComponent
className={css.displayBox}
onClick={handleMoreCardClick}
spotlightId={'bestseller-item-more-btn'}
aria-label="See more button"
></SpottableComponent>
</div>
)}
</TScroller>
</Container>
);
};
export default BestSeller;