248 lines
6.8 KiB
JavaScript
248 lines
6.8 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 { pushPanel, updatePanel } from "../../../actions/panelActions";
|
|
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
|
|
import TItemCard from "../../../components/TItemCard/TItemCard";
|
|
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 [drawChk, setDrawChk] = useState(false);
|
|
const [firstChk, setFirstChk] = useState(0);
|
|
|
|
const orderStyle = useMemo(() => ({ order: order }), [order]);
|
|
|
|
useEffect(() => {
|
|
setDrawChk(true);
|
|
}, [bestSellerDatas]);
|
|
|
|
const handleCardClick = useCallback(
|
|
(patnrId, prdtId) => () => {
|
|
dispatch(
|
|
pushPanel({
|
|
name: panel_names.DETAIL_PANEL,
|
|
panelInfo: { patnrId: patnrId, prdtId: prdtId },
|
|
})
|
|
);
|
|
},
|
|
[dispatch]
|
|
);
|
|
|
|
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
|
|
>
|
|
{bestSellerDatas &&
|
|
bestSellerDatas.map(
|
|
(
|
|
{
|
|
prdtId,
|
|
imgUrl,
|
|
priceInfo,
|
|
prdtNm,
|
|
rankOrd,
|
|
patnrId,
|
|
offerInfo,
|
|
brndNm,
|
|
patncNm,
|
|
catNm,
|
|
},
|
|
itemIndex
|
|
) => {
|
|
const rankText =
|
|
rankOrd === 1
|
|
? rankOrd + "st"
|
|
: rankOrd === 2
|
|
? rankOrd + "nd"
|
|
: rankOrd === 3
|
|
? rankOrd + "rd"
|
|
: rankOrd + "th";
|
|
return (
|
|
<TItemCard
|
|
key={"subItem" + itemIndex}
|
|
contextName={LOG_CONTEXT_NAME.HOME}
|
|
messageId={LOG_MESSAGE_ID.SHELF_CLICK}
|
|
location={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 " + bestSellerDatas.length}
|
|
lastLabel=" go to detail, button"
|
|
/>
|
|
);
|
|
}
|
|
)}
|
|
|
|
{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;
|