[FeaturedBrandsPanel] CATEGORY, twoDepth Nav & Contents 추가

Detail Notes :

1. twoDepth Nav UI 구현
2. Contents 추가
This commit is contained in:
younghoon100.park
2024-02-27 17:56:15 +09:00
parent 8e1e7edaa9
commit ed88473d83
12 changed files with 316 additions and 71 deletions

View File

@@ -170,8 +170,8 @@ export default function FeaturedBrandsPanel() {
}, [selectedSeriesId, dispatch]);
useEffect(() => {
if (selectedCatCdLv1) {
console.log("@@ [selectedCatCdLv1 sideEffect]");
if (selectedCatCdLv1 || selectedCatCdLv1 === "") {
console.log("@@ [catCdLv1 sideEffect]");
dispatch(
getBrandCategoryInfo({
@@ -183,6 +183,20 @@ export default function FeaturedBrandsPanel() {
}
}, [selectedCatCdLv1, dispatch]);
useEffect(() => {
if (selectedCatCdLv2 || selectedCatCdLv2 === "") {
console.log("@@ [catCdLv2 sideEffect]");
dispatch(
getBrandCategoryInfo({
patnrId: selectedPatnrId,
catCdLv1: selectedCatCdLv1,
catCdLv2: selectedCatCdLv2,
})
);
}
}, [selectedCatCdLv2, dispatch]);
useEffect(() => {
// @@pyh Todo, 진입시 focuse 기능 추가
}, []);
@@ -258,8 +272,11 @@ export default function FeaturedBrandsPanel() {
brandCategoryProductInfo && ( // @@pyh Todo, 현재 데이터 존재 하지 않음 ,노출 조건 문의 (현재 노출 조건 존재 하지 않음)
<FeaturedCategory
brandCategoryInfo={brandCategoryInfo}
brandCategoryProductInfo={brandCategoryProductInfo}
selectedCatCdLv1={selectedCatCdLv1}
selectedCatCdLv2={selectedCatCdLv2}
setSelectedCatCdLv1={setSelectedCatCdLv1}
setSelectedCatCdLv2={setSelectedCatCdLv2}
/>
)}
</TBody>

View File

@@ -3,7 +3,9 @@ import React from "react";
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
import { $L } from "../../../utils/helperMethods";
import css from "./FeaturedCategory.module.less";
import FeaturedCategoryContents from "./FeaturedCategoryContents/FeaturedCategoryContents";
import FeaturedCategoryNav from "./FeaturedCategoryNav/FeaturedCategoryNav";
import FeaturedSubCategoryNav from "./FeaturedSubCategoryNav/FeaturedSubCategoryNav";
const STRING_CONF = {
CATEGORY: $L("CATEGORY"),
@@ -11,9 +13,20 @@ const STRING_CONF = {
export default function FeaturedCategory({
brandCategoryInfo,
brandCategoryProductInfo,
selectedCatCdLv1,
selectedCatCdLv2,
setSelectedCatCdLv1,
setSelectedCatCdLv2,
}) {
const catCdLv1Array = brandCategoryInfo.map((obj) => obj["catCdLv1"]);
const brandCategoryProductInfoLv1 = brandCategoryProductInfo.filter(
({ catCd }) => catCdLv1Array.includes(catCd)
);
const brandCategoryProductInfoLv2 = brandCategoryProductInfo.filter(
({ catCd }) => !catCdLv1Array.includes(catCd)
);
return (
<div className={css.container}>
<SectionTitle title={STRING_CONF.CATEGORY} />
@@ -22,6 +35,56 @@ export default function FeaturedCategory({
selectedCatCdLv1={selectedCatCdLv1}
setSelectedCatCdLv1={setSelectedCatCdLv1}
/>
{selectedCatCdLv1 && (
<FeaturedSubCategoryNav
brandCategoryInfo={brandCategoryInfo}
selectedCatCdLv1={selectedCatCdLv1}
selectedCatCdLv2={selectedCatCdLv2}
setSelectedCatCdLv2={setSelectedCatCdLv2}
/>
)}
{!selectedCatCdLv1 && (
<>
{brandCategoryProductInfoLv1 &&
brandCategoryProductInfoLv1.map(
(
{ brandCategoryProductDetailInfo, catCd, catNm, patnrId },
index
) => (
<FeaturedCategoryContents
brandCategoryProductDetailInfo={
brandCategoryProductDetailInfo
}
catCd={catCd}
catNm={catNm}
key={"brandCategoryProductInfoLv1-" + index}
patnrId={patnrId}
/>
)
)}
</>
)}
{selectedCatCdLv1 && (!selectedCatCdLv2 || selectedCatCdLv2) && (
<>
{brandCategoryProductInfoLv2 &&
brandCategoryProductInfoLv2.map(
(
{ brandCategoryProductDetailInfo, catCd, catNm, patnrId },
index
) => (
<FeaturedCategoryContents
brandCategoryProductDetailInfo={
brandCategoryProductDetailInfo
}
catCd={catCd}
catNm={catNm}
key={"brandCategoryProductInfoLv1-" + index}
patnrId={patnrId}
/>
)
)}
</>
)}
</div>
);
}

View File

@@ -0,0 +1,20 @@
import React from "react";
import css from "./FeaturedCategoryContents.module.less";
import FeaturedCategoryProductList from "./FeaturedCategoryProductList/FeaturedCategoryProductList";
export default function FeaturedCategoryContents({
brandCategoryProductDetailInfo,
catNm,
patnrId,
}) {
return (
<div className={css.container}>
<h3>{catNm}</h3>
<FeaturedCategoryProductList
brandCategoryProductDetailInfo={brandCategoryProductDetailInfo}
patnrId={patnrId}
/>
</div>
);
}

View File

@@ -0,0 +1,13 @@
@import "../../../../style/CommonStyle.module.less";
@import "../../../../style/utils.module.less";
.container {
margin-bottom: 36px;
padding-left: 60px;
h3 {
margin-bottom: 12px;
.font(@fontFamily: @baseFontBold, @fontSize: 36px);
color: @COLOR_GRAY08;
}
}

View File

@@ -0,0 +1,62 @@
import React, { useCallback } from "react";
import { useDispatch } from "react-redux";
import { pushPanel } from "../../../../../actions/panelActions";
import TItemCard from "../../../../../components/TItemCard/TItemCard";
import TVirtualGridList from "../../../../../components/TVirtualGridList/TVirtualGridList";
import { panel_names } from "../../../../../utils/Config";
import css from "./FeaturedCategoryProductList.module.less";
export default function FeaturedCategoryProductList({
brandCategoryProductDetailInfo,
patnrId,
}) {
const dispatch = useDispatch();
const renderItem = useCallback(
({ index, ...rest }) => {
const { imgUrl, prdtId, prdtNm, priceInfo } =
brandCategoryProductDetailInfo[index];
const handleClick = () => {
dispatch(
pushPanel({
name: panel_names.DETAIL_PANEL,
panelInfo: { patnrId, prdtId },
})
);
};
return (
<TItemCard
imageAlt={prdtNm}
imageSource={imgUrl}
onClick={handleClick}
priceInfo={priceInfo}
productId={prdtId}
productName={prdtNm}
{...rest}
/>
);
},
[brandCategoryProductDetailInfo, dispatch, patnrId]
);
return (
<div className={css.container}>
{brandCategoryProductDetailInfo && (
<TVirtualGridList
// cbScrollTo={getScrollTo}
className={css.tVirtualGridList}
dataSize={brandCategoryProductDetailInfo.length}
direction="horizontal"
itemHeight={438}
itemWidth={324}
spacing={18}
renderItem={renderItem}
/>
)}
</div>
);
}

View File

@@ -0,0 +1,15 @@
@import "../../../../../style/CommonStyle.module.less";
@import "../../../../../style/utils.module.less";
.container {
position: relative;
.size(@w: 100%, @h: 438px);
.tVirtualGridList {
overflow: unset;
> div {
overflow: unset !important;
}
}
}

View File

@@ -0,0 +1,6 @@
{
"main": "FeaturedCategoryProductList.jsx",
"styles": [
"FeaturedCategoryProductList.module.less"
]
}

View File

@@ -0,0 +1,6 @@
{
"main": "FeaturedCategoryContents.jsx",
"styles": [
"FeaturedCategoryContents.module.less"
]
}

View File

@@ -1,4 +1,4 @@
import React, { useCallback, useEffect } from "react";
import React, { useCallback } from "react";
import Scroller from "@enact/sandstone/Scroller";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
@@ -6,7 +6,7 @@ import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDeco
import TButton, { TYPES } from "../../../../components/TButton/TButton";
import useScrollReset from "../../../../hooks/useScrollReset";
import useScrollTo from "../../../../hooks/useScrollTo";
import FeaturedSubCategoryNav from "../FeaturedSubCategoryNav/FeaturedSubCategoryNav";
import { $L } from "../../../../utils/helperMethods";
import css from "./FeaturedCategoryNav.module.less";
const Container = SpotlightContainerDecorator(
@@ -14,6 +14,10 @@ const Container = SpotlightContainerDecorator(
"nav"
);
const STRING_CONF = {
ALL: $L("ALL"),
};
export default function FeaturedCategoryNav({
brandCategoryInfo,
selectedCatCdLv1,
@@ -30,16 +34,13 @@ export default function FeaturedCategoryNav({
}, []);
const handleClick = useCallback((catCdLv1) => {
catCdLv1 ? setSelectedCatCdLv1(catCdLv1) : setSelectedCatCdLv1("");
setSelectedCatCdLv1(catCdLv1);
}, []);
const handleFocus = useCallback(() => {
handleScrollReset();
}, []);
useEffect(() => {
scrollLeft();
}, [selectedCatCdLv1]);
return (
<Container className={css.nav}>
<Scroller
@@ -54,52 +55,33 @@ export default function FeaturedCategoryNav({
<TButton
className={!selectedCatCdLv1 && css.selected}
onBlur={handleBlur}
onClick={handleClick}
onClick={() => handleClick("")}
onFocus={handleFocus}
selected={!selectedCatCdLv1}
type={TYPES.oneDepthCategory}
>
{"ALL"}
{STRING_CONF.ALL}
</TButton>
</li>
{brandCategoryInfo &&
brandCategoryInfo.map(
(
// @@pyh Todo, delete comment
{
catCdLv1,
catNmLv1,
// categoryLv2Infos,
// patnrId,
// prdtCnt
},
index
) => (
<li key={"brandCategoryInfo-" + index}>
<TButton
className={
selectedCatCdLv1 &&
selectedCatCdLv1 === catCdLv1 &&
css.selected
}
onClick={() => handleClick(catCdLv1)}
selected={selectedCatCdLv1 && selectedCatCdLv1 === catCdLv1}
type={TYPES.oneDepthCategory}
>
{catNmLv1}
</TButton>
</li>
)
)}
brandCategoryInfo.map(({ catCdLv1, catNmLv1 }) => (
<li key={"brandCategoryInfo-" + catCdLv1}>
<TButton
className={
selectedCatCdLv1 &&
selectedCatCdLv1 === catCdLv1 &&
css.selected
}
onClick={() => handleClick(catCdLv1)}
selected={selectedCatCdLv1 && selectedCatCdLv1 === catCdLv1}
type={TYPES.oneDepthCategory}
>
{catNmLv1}
</TButton>
</li>
))}
</ul>
</Scroller>
{selectedCatCdLv1 && (
<FeaturedSubCategoryNav
brandCategoryInfo={brandCategoryInfo}
selectedCatCdLv1={selectedCatCdLv1}
/>
)}
</Container>
);
}

View File

@@ -3,7 +3,6 @@
.nav {
.size(@w: 100%, @h: 162px);
height: 162px;
margin-bottom: 12px;
background-color: #ddd;

View File

@@ -1,4 +1,4 @@
import React from "react";
import React, { useCallback } from "react";
import Scroller from "@enact/sandstone/Scroller";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
@@ -6,6 +6,7 @@ import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDeco
import TButton, { TYPES } from "../../../../components/TButton/TButton";
import useScrollReset from "../../../../hooks/useScrollReset";
import useScrollTo from "../../../../hooks/useScrollTo";
import { $L } from "../../../../utils/helperMethods";
import css from "./FeaturedSubCategoryNav.module.less";
const Container = SpotlightContainerDecorator(
@@ -13,42 +14,82 @@ const Container = SpotlightContainerDecorator(
"nav"
);
const STRING_CONF = {
ALL: $L("ALL"),
};
export default function FeaturedSubCategoryNav({
brandCategoryInfo,
selectedCatCdLv1,
selectedCatCdLv2,
setSelectedCatCdLv2,
}) {
const { getScrollTo, scrollLeft } = useScrollTo();
const { handleScrollReset, handleStopScrolling } = useScrollReset(
scrollLeft,
true
);
const handleBlur = useCallback(() => {
handleStopScrolling();
}, []);
const handleClick = useCallback((catCdLv2) => {
setSelectedCatCdLv2(catCdLv2);
}, []);
const handleFocus = useCallback(() => {
handleScrollReset();
}, []);
return (
<Container className={css.nav}>
<Scroller
// cbScrollTo={getScrollTo}
cbScrollTo={getScrollTo}
direction="horizontal"
horizontalScrollbar="hidden"
noScrollByWheel
scrollMode="translate"
>
<ul>
{brandCategoryInfo &&
brandCategoryInfo
.filter(({ catCdLv1 }, index) => catCdLv1 === selectedCatCdLv1)
.map(({ catCdLv1, catNmLv1, categoryLv2Infos }, index) => (
<div key={"categoryLv1Infos-" + index}>
{categoryLv2Infos &&
categoryLv2Infos.map(({ catCdLv2, catNmLv2 }, idx) => (
<li key={"categoryLv2Infos-" + idx}>
<TButton
// selected={}
size={null}
color={null}
type={TYPES.twoDepthCategory}
withMarquee
>
{catNmLv2}
</TButton>
</li>
))}
</div>
))}
</ul>
{brandCategoryInfo &&
brandCategoryInfo
.filter(({ catCdLv1 }) => catCdLv1 === selectedCatCdLv1)
.map(({ categoryLv2Infos }, index) => (
<ul key={"categoryLv1Infos-" + index}>
<li>
<TButton
className={css.tButton}
color={null}
onBlur={handleBlur}
onClick={() => handleClick("")}
onFocus={handleFocus}
selected={!selectedCatCdLv2}
size={null}
type={TYPES.twoDepthCategory}
withMarquee
>
{STRING_CONF.ALL}
</TButton>
</li>
{categoryLv2Infos &&
categoryLv2Infos.map(({ catCdLv2, catNmLv2 }, idx) => (
<li key={"categoryLv2Infos-" + idx}>
<TButton
selected={
selectedCatCdLv2 && selectedCatCdLv2 === catCdLv2
}
size={null}
color={null}
onClick={() => handleClick(catCdLv2)}
type={TYPES.twoDepthCategory}
withMarquee
>
{catNmLv2}
</TButton>
</li>
))}
</ul>
))}
</Scroller>
</Container>
);

View File

@@ -1,2 +1,23 @@
@import "../../../../style/CommonStyle.module.less";
@import "../../../../style/utils.module.less";
.nav {
.size(@w: 100%, @h: 132px);
margin-bottom: 12px;
background-color: #e9e9e9;
ul {
display: flex;
align-items: center;
height: inherit;
padding-left: 60px;
li {
margin-right: 12px;
.tButton {
width: 180px;
}
}
}
}