[OnSalePanel] component, props 수정

Detail Notes :

1. TVirtualGridList 반영
2. props 변경
This commit is contained in:
younghoon100.park
2024-02-20 14:17:12 +09:00
parent 3ed8fd1331
commit 61474969a5
7 changed files with 106 additions and 134 deletions

View File

@@ -1,10 +1,8 @@
import React, { useCallback } from "react";
import { VirtualGridList } from "@enact/sandstone/VirtualList";
import { setContainerLastFocusedElement } from "@enact/spotlight/src/container";
import { scaleH, scaleW } from "../../../utils/helperMethods";
import { SpotlightIds } from "../../../utils/SpotlightIds";
import CategoryNavItem from "../CategoryNav/CategoryNavItem/CategoryNavItem";
import css from "./CategoryNav.module.less";
@@ -16,42 +14,29 @@ const LIST_ITEM_CONF = {
export default function CategoryNav({
categoryInfos,
currentCategoryCode,
scrollTop,
setCurrentCategoryCode,
...rest
selectedLgCatCd,
setSelectedLgCatCd,
}) {
const handleCategoryNavClick = useCallback(
(categoryCode) => {
if (currentCategoryCode === categoryCode) {
return scrollTop();
}
setContainerLastFocusedElement(null, [SpotlightIds.TBODY]);
setCurrentCategoryCode(categoryCode);
scrollTop();
},
[currentCategoryCode]
);
const renderItem = useCallback(
({ index, ...rest }) => {
return (
<CategoryNavItem
categoryInfos={categoryInfos}
currentCategoryCode={currentCategoryCode}
onCategoryNavClick={handleCategoryNavClick}
index={index}
scrollTop={scrollTop}
selectedLgCatCd={selectedLgCatCd}
setSelectedLgCatCd={setSelectedLgCatCd}
{...rest}
/>
);
},
[categoryInfos, currentCategoryCode, handleCategoryNavClick]
[categoryInfos, selectedLgCatCd]
);
return (
<nav className={css.container} {...rest}>
{categoryInfos && categoryInfos.length > 0 && (
<nav className={css.container}>
{categoryInfos && (
<VirtualGridList
className={css.virtualGridList}
dataSize={categoryInfos.length}

View File

@@ -3,45 +3,51 @@ import React, { memo, useCallback } from "react";
import classNames from "classnames";
import Spottable from "@enact/spotlight/Spottable";
import { setContainerLastFocusedElement } from "@enact/spotlight/src/container";
import { SpotlightIds } from "../../../../utils/SpotlightIds";
import css from "./CategoryNavItem.module.less";
const SpottableComponent = Spottable("div");
export default memo(function CategoryNavItem({
categoryInfos,
currentCategoryCode,
onCategoryNavClick,
index,
scrollTop,
selectedLgCatCd,
setSelectedLgCatCd,
...rest
}) {
const {
lgCatCd: categoryCode,
lgCatNm: categoryName, //
} = categoryInfos[index];
const { lgCatCd, lgCatNm } = categoryInfos[index];
const handleClick = useCallback(
(categoryCode) => {
onCategoryNavClick && onCategoryNavClick(categoryCode);
(lgCatCd) => {
if (selectedLgCatCd === lgCatCd) {
return scrollTop();
}
setContainerLastFocusedElement(null, [SpotlightIds.TBODY]);
setSelectedLgCatCd(lgCatCd);
scrollTop();
},
[categoryCode, currentCategoryCode]
[selectedLgCatCd]
);
return (
<SpottableComponent
className={classNames(
css.category,
categoryCode === currentCategoryCode && css.selected
css.categoryInfo,
lgCatCd === selectedLgCatCd && css.selected
)}
key={"categoryInfo-" + index}
onClick={() => handleClick(categoryCode)}
spotlightId={"spotlightId-" + categoryCode}
onClick={() => handleClick(lgCatCd)}
spotlightId={"spotlightId-" + lgCatCd}
{...rest}
>
<div>
<span className={css[`category-icon-${categoryCode}`]} />
<span className={css["categoryInfoIcon-" + lgCatCd]} />
</div>
<strong>{categoryName}</strong>
<strong>{lgCatNm}</strong>
</SpottableComponent>
);
});

View File

@@ -1,7 +1,7 @@
@import "../../../../style/CommonStyle.module.less";
@import "../../../../style/utils.module.less";
.category {
.categoryInfo {
/* normal */
position: relative;
.flex(@direction: column);
@@ -22,63 +22,63 @@
background-position: center;
background-size: cover;
&.category-icon-1017 {
&.categoryInfoIcon-1017 {
// LG Electronics
background-image: url("../../../../../assets/images/icons/ic-category-lgelectronics-nor@3x.png");
}
// Garden and Outdoors
&.category-icon-1008 {
&.categoryInfoIcon-1008 {
background-image: url("../../../../../assets/images/icons/ic-category-garden-nor@3x.png");
}
// Fashion
&.category-icon-1000 {
&.categoryInfoIcon-1000 {
background-image: url("../../../../../assets/images/icons/ic-category-fashion-nor@3x.png");
}
// Beauty
&.category-icon-1003 {
&.categoryInfoIcon-1003 {
background-image: url("../../../../../assets/images/icons/ic-category-beauty-nor@3x.png");
}
// Jewelry
&.category-icon-1004 {
&.categoryInfoIcon-1004 {
background-image: url("../../../../../assets/images/icons/ic-category-jewelry-nor@3x.png");
}
// Home
&.category-icon-1006 {
&.categoryInfoIcon-1006 {
background-image: url("../../../../../assets/images/icons/ic-category-home-nor@3x.png");
}
// Kitchen & Food
&.category-icon-1007 {
&.categoryInfoIcon-1007 {
background-image: url("../../../../../assets/images/icons/ic-category-kitchen-nor@3x.png");
}
// Accessories
&.category-icon-1014 {
&.categoryInfoIcon-1014 {
background-image: url("../../../../../assets/images/icons/ic-category-accessories-nor@3x.png");
}
// Heaclth & Fitness
&.category-icon-1009 {
&.categoryInfoIcon-1009 {
background-image: url("../../../../../assets/images/icons/ic-category-health-nor@3x.png");
}
// Crafts & Sewing
&.category-icon-1011 {
&.categoryInfoIcon-1011 {
background-image: url("../../../../../assets/images/icons/ic-category-cw-nor@3x.png");
}
// Electronics
&.category-icon-1010 {
&.categoryInfoIcon-1010 {
background-image: url("../../../../../assets/images/icons/ic-category-electronics-nor@3x.png");
}
// Clearance
&.category-icon-1013 {
&.categoryInfoIcon-1013 {
background-image: url("../../../../../assets/images/icons/ic-category-clearance-nor@3x.png");
}
}
@@ -106,62 +106,62 @@
span {
// LG Electronics
&.category-icon-1017 {
&.categoryInfoIcon-1017 {
background-image: url("../../../../../assets/images/icons/ic-category-lgelectronics-foc@3x.png");
}
// Garden and Outdoors
&.category-icon-1008 {
&.categoryInfoIcon-1008 {
background-image: url("../../../../../assets/images/icons/ic-category-garden-foc@3x.png");
}
// Fashion
&.category-icon-1000 {
&.categoryInfoIcon-1000 {
background-image: url("../../../../../assets/images/icons/ic-category-fashion-foc@3x.png");
}
// Beauty
&.category-icon-1003 {
&.categoryInfoIcon-1003 {
background-image: url("../../../../../assets/images/icons/ic-category-beauty-foc@3x.png");
}
// Jewelry
&.category-icon-1004 {
&.categoryInfoIcon-1004 {
background-image: url("../../../../../assets/images/icons/ic-category-jewelry-foc@3x.png");
}
// Home
&.category-icon-1006 {
&.categoryInfoIcon-1006 {
background-image: url("../../../../../assets/images/icons/ic-category-home-foc@3x.png");
}
// Kitchen & Food
&.category-icon-1007 {
&.categoryInfoIcon-1007 {
background-image: url("../../../../../assets/images/icons/ic-category-kitchen-foc@3x.png");
}
// Accessories
&.category-icon-1014 {
&.categoryInfoIcon-1014 {
background-image: url("../../../../../assets/images/icons/ic-category-accessories-foc@3x.png");
}
// Heaclth & Fitness
&.category-icon-1009 {
&.categoryInfoIcon-1009 {
background-image: url("../../../../../assets/images/icons/ic-category-health-foc@3x.png");
}
// Crafts & Sewing
&.category-icon-1011 {
&.categoryInfoIcon-1011 {
background-image: url("../../../../../assets/images/icons/ic-category-cw-foc@3x.png");
}
// Electronics
&.category-icon-1010 {
&.categoryInfoIcon-1010 {
background-image: url("../../../../../assets/images/icons/ic-category-electronics-foc@3x.png");
}
// Clearance
&.category-icon-1013 {
&.categoryInfoIcon-1013 {
background-image: url("../../../../../assets/images/icons/ic-category-clearance-foc@3x.png");
}
}

View File

@@ -24,40 +24,40 @@ export default function OnSalePanel() {
);
const saleInfos = useSelector((state) => state.onSale.onSaleData.saleInfos);
const [currentCategoryCode, setCurrentCategoryCode] = useState();
const [initialLoad, setInitialLoad] = useState(true);
const [selectedLgCatCd, setSelectedLgCatCd] = useState();
const [isInitialLoad, setIsInitialLoad] = useState(true);
const [isTopButtonClicked, setIsTopButtonClicked] = useState(false);
const [targetId, setTargetId] = useState();
const timerRef = useRef();
useEffect(() => {
if (categoryInfos && !currentCategoryCode) {
setCurrentCategoryCode(categoryInfos[0].lgCatCd);
if (categoryInfos && !selectedLgCatCd) {
setSelectedLgCatCd(categoryInfos[0].lgCatCd);
}
}, []);
useEffect(() => {
if (currentCategoryCode) {
if (selectedLgCatCd) {
dispatch(
getOnSaleInfo({ categoryIncFlag: "Y", lgCatCd: currentCategoryCode })
getOnSaleInfo({ categoryIncFlag: "Y", lgCatCd: selectedLgCatCd })
);
}
}, [currentCategoryCode, dispatch]);
}, [selectedLgCatCd, dispatch]);
useEffect(() => {
if (saleInfos) {
const productId = saleInfos[0].saleProductInfos[0].prdtId;
setTargetId("spotlightId-" + removeDotAndColon(productId));
const prdtId = saleInfos[0].saleProductInfos[0].prdtId;
setTargetId("spotlightId-" + removeDotAndColon(prdtId));
}
}, [dispatch, saleInfos]);
useEffect(() => {
if (currentCategoryCode && initialLoad) {
Spotlight.focus("spotlightId-" + currentCategoryCode);
setInitialLoad(false);
if (selectedLgCatCd && isInitialLoad) {
Spotlight.focus("spotlightId-" + selectedLgCatCd);
setIsInitialLoad(false);
}
}, [currentCategoryCode, initialLoad]);
}, [selectedLgCatCd, isInitialLoad]);
useEffect(() => {
return () => clearTimeout(timerRef.current);
@@ -76,18 +76,18 @@ export default function OnSalePanel() {
<TPanel className={css.container}>
<CategoryNav
categoryInfos={categoryInfos}
currentCategoryCode={currentCategoryCode}
scrollTop={scrollTop}
setCurrentCategoryCode={setCurrentCategoryCode}
selectedLgCatCd={selectedLgCatCd}
setSelectedLgCatCd={setSelectedLgCatCd}
/>
<TBody className={css.tBody} cbScrollTo={getScrollTo}>
{saleInfos &&
saleInfos.map(({ saleNm, saleProductInfos, expsOrd }, index) => (
<OnSaleProductList
exposureOrder={expsOrd}
expsOrd={expsOrd}
key={"saleInfo-" + index}
isTopButtonClicked={isTopButtonClicked}
saleName={saleNm}
saleNm={saleNm}
saleProductInfos={saleProductInfos}
setIsTopButtonClicked={setIsTopButtonClicked}
/>

View File

@@ -8,14 +8,19 @@ import { panel_names } from "../../../../utils/Config";
import css from "./OnSaleProductItem.module.less";
export default memo(function OnSaleProductItem({
index,
saleProductInfos,
imgUrl,
patnrId,
prdtId,
prdtNm,
priceInfo,
...rest
}) {
const dispatch = useDispatch();
delete rest.lgCatCd;
delete rest.lgCatNm;
delete rest.offerInfo;
delete rest.patncNm;
const { imgUrl, patnrId, prdtId, prdtNm, priceInfo } =
saleProductInfos[index];
const dispatch = useDispatch();
const handleCardClick = useCallback(() => {
dispatch(
@@ -24,7 +29,7 @@ export default memo(function OnSaleProductItem({
panelInfo: { patnrId, prdtId },
})
);
}, [dispatch, saleProductInfos]);
}, [dispatch, patnrId, prdtId]);
return (
<div className={css.container}>
@@ -32,10 +37,10 @@ export default memo(function OnSaleProductItem({
<TItemCard
imageAlt={prdtNm}
imageSource={imgUrl}
onCardClick={handleCardClick}
priceInfo={priceInfo}
productId={prdtId}
productName={prdtNm}
onCardClick={handleCardClick}
{...rest}
/>
</div>

View File

@@ -1,35 +1,27 @@
import React, { useCallback, useEffect } from "react";
import React, { useEffect } from "react";
import { VirtualGridList } from "@enact/sandstone/VirtualList";
import {
getContainerId,
setContainerLastFocusedElement,
} from "@enact/spotlight/src/container";
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
import TVirtualGridList from "../../../components/TVirtualGridList/TVirtualGridList";
import useScrollTo from "../../../hooks/useScrollTo";
import { scaleH, scaleW } from "../../../utils/helperMethods";
import OnSaleProductItem from "../OnSaleProductList/OnSaleProductItem/OnSaleProductItem";
import css from "./OnSaleProductList.module.less";
const LIST_ITEM_CONF = {
ITEM_WIDTH: 324,
ITEM_HEIGHT: 570,
SAPCING: 18,
};
export default function OnSaleProductList({
exposureOrder,
expsOrd,
isTopButtonClicked,
saleName,
saleNm,
saleProductInfos,
setIsTopButtonClicked,
...rest
}) {
const { getScrollTo, scrollLeft } = useScrollTo();
useEffect(() => {
const containerId = "container-" + exposureOrder;
const containerId = "container-" + expsOrd;
const container = document.getElementById(containerId);
if (container) {
@@ -42,45 +34,29 @@ export default function OnSaleProductList({
}, [saleProductInfos]);
useEffect(() => {
if (exposureOrder === 1 && isTopButtonClicked) {
if (expsOrd === 1 && isTopButtonClicked) {
scrollLeft();
setIsTopButtonClicked(false);
}
}, [isTopButtonClicked]);
const renderItem = useCallback(
({ index, ...rest }) => {
return (
<OnSaleProductItem
index={index}
saleProductInfos={saleProductInfos}
{...rest}
/>
);
},
[saleProductInfos]
);
return (
<div className={css.container} id={"container-" + exposureOrder} {...rest}>
{saleName && <SectionTitle title={saleName} />}
{saleProductInfos && (
<VirtualGridList
cbScrollTo={getScrollTo}
className={css.virtualGridList}
dataSize={saleProductInfos.length}
direction="horizontal"
horizontalScrollbar="hidden"
itemRenderer={renderItem}
itemSize={{
minWidth: scaleW(LIST_ITEM_CONF.ITEM_WIDTH),
minHeight: scaleH(LIST_ITEM_CONF.ITEM_HEIGHT),
}}
noScrollByWheel
scrollMode="translate"
spacing={scaleW(LIST_ITEM_CONF.SAPCING)}
/>
<div className={css.container} id={"container-" + expsOrd}>
{saleNm && saleProductInfos && (
<>
<SectionTitle title={saleNm} />
<TVirtualGridList
cbScrollTo={getScrollTo}
className={css.tVirtualGridList}
dataSize={saleProductInfos.length}
direction="horizontal"
items={saleProductInfos}
itemCard={OnSaleProductItem}
itemHeight={570}
itemWidth={324}
spacing={18}
/>
</>
)}
</div>
);

View File

@@ -11,7 +11,7 @@
.position(@position: absolute, @top: 58px, @left: 60px);
}
.virtualGridList {
.tVirtualGridList {
overflow: unset;
> div {