[FeaturedBrandsPanel] section FEATURED CREATORS 추가 및 수정

Detail Notes :

1. FEATURED CREATORS 추가
2. RecommendedShowsContents, “containerId-“ → “recommendedShowsContentsId-“ 수정
This commit is contained in:
younghoon100.park
2024-02-26 13:23:27 +09:00
parent 1d0c52cd67
commit ed1c2c3629
14 changed files with 436 additions and 4 deletions

View File

@@ -4,6 +4,7 @@ import { useDispatch, useSelector } from "react-redux";
import {
getBrandBestSeller,
getBrandCreatorsInfo,
getBrandLayoutInfo,
getBrandList,
getBrandLiveChannelInfo,
@@ -15,6 +16,7 @@ import TPanel from "../../components/TPanel/TPanel";
import Banner from "./Banner/Banner";
import FeaturedBestSeller from "./FeaturedBestSeller/FeaturedBestSeller";
import css from "./FeaturedBrandsPanel.module.less";
import FeaturedCreators from "./FeaturedCreators/FeaturedCreators";
import LiveChannels from "./LiveChannels/LiveChannels";
import QuickMenu from "./QuickMenu/QuickMenu";
import RecommendedShows from "./RecommendedShows/RecommendedShows";
@@ -59,10 +61,18 @@ export default function FeaturedBrandsPanel() {
const brandRecommendedShowInfo = useSelector(
(state) => state.brand.brandRecommendedShowInfoData.brandRecommendedShowInfo
);
const brandCreatorsInfo = useSelector(
(state) => state.brand.brandCreatorsInfoData.brandCreatorsInfo
);
// @@pyh Todo, 브랜드도 아니고 발은드라..
const barndCreatorsShowInfo = useSelector(
(state) => state.brand.brandCreatorsInfoData.barndCreatorsShowInfo
);
const [selectedPatnrId, setSelectedPatnrId] = useState(panelInfo.toString());
const [selectedBrandInfo, setSelectedBrandInfo] = useState();
const [selectedCatCd, setSelectedCatCd] = useState();
const [selectedHstNm, setSelectedHstNm] = useState();
useEffect(() => {
if (!brandInfo) {
@@ -86,6 +96,7 @@ export default function FeaturedBrandsPanel() {
dispatch(
getBrandRecommendedShowInfo({ patnrId: selectedPatnrId, catCd: "" })
);
dispatch(getBrandCreatorsInfo({ patnrId: selectedPatnrId, hstNm: "" }));
}
}, [brandInfo, dispatch, selectedPatnrId]);
@@ -102,6 +113,16 @@ export default function FeaturedBrandsPanel() {
}
}, [selectedCatCd, dispatch]);
useEffect(() => {
if (selectedHstNm) {
console.log("@@ [hstNm sideEffect]");
dispatch(
getBrandCreatorsInfo({ hstNm: selectedHstNm, patnrId: selectedPatnrId })
);
}
}, [selectedHstNm, dispatch]);
useEffect(() => {
// @@pyh Todo, 진입시 focuse 기능 추가
}, []);
@@ -152,8 +173,19 @@ export default function FeaturedBrandsPanel() {
}
brandRecommendedShowInfo={brandRecommendedShowInfo}
selectedCatCd={selectedCatCd}
setSelectedCatCd={setSelectedCatCd}
selectedPatnrId={selectedPatnrId}
setSelectedCatCd={setSelectedCatCd}
/>
)}
{brandCreatorsInfo &&
barndCreatorsShowInfo && ( // @@pyh Todo, 노출 조건 문의 (현재 노출 조건 존재 하지 않음)
<FeaturedCreators
brandCreatorsInfo={brandCreatorsInfo}
barndCreatorsShowInfo={barndCreatorsShowInfo}
selectedHstNm={selectedHstNm}
selectedPatnrId={selectedPatnrId}
setSelectedHstNm={setSelectedHstNm}
/>
)}
</TBody>

View File

@@ -0,0 +1,69 @@
import React from "react";
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
import { $L } from "../../../utils/helperMethods";
import css from "./FeaturedCreators.module.less";
import FeaturedCreatorsContents from "./FeaturedCreatorsContents/FeaturedCreatorsContents";
import FeaturedCreatorsNav from "./FeaturedCreatorsNav/FeaturedCreatorsNav";
const STRING_CONF = {
FEATURED_CREATORS: $L("FEATURED CREATORS"),
};
export default function FeaturedCreators({
brandCreatorsInfo,
barndCreatorsShowInfo,
selectedHstNm,
selectedPatnrId,
setSelectedHstNm,
}) {
return (
<div className={css.container}>
<SectionTitle title={STRING_CONF.FEATURED_CREATORS} />
<FeaturedCreatorsNav
brandCreatorsInfo={brandCreatorsInfo}
selectedHstNm={selectedHstNm}
selectedPatnrId={selectedPatnrId}
setSelectedHstNm={setSelectedHstNm}
/>
{barndCreatorsShowInfo &&
barndCreatorsShowInfo.map(
(
// @@pyh Todo, delete comment later
{
brandCreatorsProductInfo,
// hostIdCval,
// hostImgPath,
// hstNm,
// logoImgAlt,
// logoImgNm,
// logoImgPath,
// pathcLogoPath,
// patncNm,
patnrId,
// prdtCnt,
showId,
showNm,
// showUrl,
thumbnailUrl,
// vtctpYn,
},
index
) => (
<FeaturedCreatorsContents
brandCreatorsProductInfo={brandCreatorsProductInfo}
index={index}
key={"barndCreatorsShowInfo-" + index}
patnrId={patnrId}
selectedHstNm={selectedHstNm}
selectedPatnrId={selectedPatnrId}
showId={showId}
showNm={showNm}
thumbnailUrl={thumbnailUrl}
/>
)
)}
</div>
);
}

View File

@@ -0,0 +1,11 @@
@import "../../../style/CommonStyle.module.less";
@import "../../../style/utils.module.less";
.container {
margin-bottom: 58px;
h2 {
margin-bottom: 24px;
padding-left: 60px;
}
}

View File

@@ -0,0 +1,66 @@
import React, { useEffect } from "react";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import {
getContainerId,
setContainerLastFocusedElement,
} from "@enact/spotlight/src/container";
import TItemCard, { TYPES } from "../../../../components/TItemCard/TItemCard";
import css from "./FeaturedCreatorsContents.module.less";
import FeaturedCreatorsProductList from "./FeaturedCreatorsProductList/FeaturedCreatorsProductList";
const Container = SpotlightContainerDecorator(
{ leaveFor: { right: "" }, enterTo: "last-focused" },
"div"
);
export default function FeaturedCreatorsContents({
brandCreatorsProductInfo,
index,
patnrId,
selectedHstNm,
selectedPatnrId,
showId,
showNm,
thumbnailUrl,
}) {
useEffect(() => {
const containerId = "featuredCreatorsContentsId-" + index;
const container = document.getElementById(containerId);
if (container) {
// change last-focus to 1st item, when changing selectedHstNm
const itemCard = container.children[0];
itemCard && setContainerLastFocusedElement(itemCard, [containerId]);
// reset last-focus of tVirtualGridList, when changing selectedHstNm
const gridListId = getContainerId(container.children[1].children[0]);
const gridList = container.children[1].children[0];
gridList && setContainerLastFocusedElement(null, [gridListId]);
}
}, [selectedHstNm]);
return (
<Container
className={css.container}
id={"featuredCreatorsContentsId-" + index}
spotlightId={"featuredCreatorsContentsId-" + index}
>
<TItemCard
imageAlt={showNm}
imageSource={thumbnailUrl}
nonPosition
productName={showNm}
productId={showId}
type={TYPES.videoShow}
/>
<FeaturedCreatorsProductList
brandCreatorsProductInfo={brandCreatorsProductInfo}
selectedHstNm={selectedHstNm}
selectedPatnrId={selectedPatnrId}
patnrId={patnrId}
/>
</Container>
);
}

View File

@@ -0,0 +1,9 @@
@import "../../../../style/CommonStyle.module.less";
@import "../../../../style/utils.module.less";
.container {
display: flex;
.size(@w: 100%, @h:438px);
margin-bottom: 36px;
padding-left: 60px;
}

View File

@@ -0,0 +1,72 @@
import React, { useCallback, useEffect } 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 useScrollTo from "../../../../../hooks/useScrollTo";
import { panel_names } from "../../../../../utils/Config";
import css from "./FeaturedCreatorsProductList.module.less";
export default function FeaturedCreatorsProductList({
brandCreatorsProductInfo,
selectedHstNm,
selectedPatnrId,
patnrId,
}) {
const { getScrollTo, scrollLeft } = useScrollTo();
const dispatch = useDispatch();
useEffect(() => {
scrollLeft();
}, [selectedHstNm, selectedPatnrId]);
const renderItem = useCallback(
({ index, ...rest }) => {
const { prdtId, prdtImgUrl, prdtNm, priceInfo, soldoutFlag } =
brandCreatorsProductInfo[index];
const handleClick = () => {
dispatch(
pushPanel({
name: panel_names.DETAIL_PANEL,
panelInfo: { patnrId, prdtId },
})
);
};
return (
<TItemCard
imageAlt={prdtNm}
imageSource={prdtImgUrl}
onClick={handleClick}
priceInfo={priceInfo}
productId={prdtId}
productName={prdtNm}
soldoutFlag={soldoutFlag}
{...rest}
/>
);
},
[brandCreatorsProductInfo, dispatch, patnrId]
);
return (
<div className={css.container}>
{brandCreatorsProductInfo && (
<TVirtualGridList
cbScrollTo={getScrollTo}
className={css.tVirtualGridList}
dataSize={brandCreatorsProductInfo.length}
direction="horizontal"
itemHeight={438}
itemWidth={324}
spacing={18}
renderItem={renderItem}
/>
)}
</div>
);
}

View File

@@ -0,0 +1,7 @@
@import "../../../../../style/utils.module.less";
.container {
.flex();
width: calc(100% - 546px);
padding-left: 18px;
}

View File

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

View File

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

View File

@@ -0,0 +1,94 @@
import React, { useCallback, useEffect } from "react";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import Scroller from "@enact/ui/Scroller";
import TButton, { TYPES } from "../../../../components/TButton/TButton";
import useScrollReset from "../../../../hooks/useScrollReset";
import useScrollTo from "../../../../hooks/useScrollTo";
import css from "./FeaturedCreatorsNav.module.less";
const Container = SpotlightContainerDecorator(
{ leaveFor: { right: "" }, enterTo: "last-focused" },
"nav"
);
export default function FeaturedCreatorsNav({
brandCreatorsInfo,
selectedHstNm,
selectedPatnrId,
setSelectedHstNm,
}) {
const { getScrollTo, scrollLeft } = useScrollTo();
const { handleScrollReset, handleStopScrolling } = useScrollReset(
scrollLeft,
true
);
const handleBlur = useCallback((index) => {
if (index !== 0) {
return;
}
handleStopScrolling();
}, []);
const handleClick = useCallback((hstNm) => {
setSelectedHstNm(hstNm);
}, []);
const handleFocus = useCallback((index) => {
if (index !== 0) {
return;
}
handleScrollReset();
}, []);
useEffect(() => {
scrollLeft();
}, [selectedPatnrId]);
return (
<Container className={css.nav}>
<Scroller
cbScrollTo={getScrollTo}
direction="horizontal"
horizontalScrollbar="hidden"
noScrollByWheel
scrollMode="translate"
>
<ul>
{brandCreatorsInfo &&
brandCreatorsInfo.map(
(
{ hostIdCval, hostImgNm, hostImgPath, hstNm, patnrId },
index
) => (
<li key={"brandCreatorsInfo-" + index}>
<TButton
avatarAlt={hostImgNm}
avatarSource={
// @@pyh Todo, request hostImgPath from harmony
"https://images.unsplash.com/photo-1518991669955-9c7e78ec80ca?q=80&w=2080&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
}
className={selectedHstNm === hstNm && css.selected}
onBlur={() => handleBlur(index)}
onClick={() => handleClick(hstNm)}
onFocus={() => handleFocus(index)}
selected={
selectedHstNm ? selectedHstNm === hstNm : index === 0
}
type={TYPES.withAvatar}
withAvatar
>
{hstNm}
</TButton>
</li>
)
)}
</ul>
</Scroller>
</Container>
);
}

View File

@@ -0,0 +1,48 @@
@import "../../../../style/CommonStyle.module.less";
@import "../../../../style/utils.module.less";
.nav {
.size(@w: 100%, @h: 162px);
margin-bottom: 12px;
background-color: #ddd;
ul {
display: flex;
align-items: center;
height: inherit;
padding-left: 60px;
border-bottom: 18px solid @BG_COLOR_01;
&::before {
position: absolute;
right: -100%;
bottom: 0;
.size(@w: 100%, @h: 18px);
background-color: @BG_COLOR_01;
content: "";
}
li {
margin-right: 12px;
> div {
position: relative;
&.selected {
&::before {
position: absolute;
bottom: -62px;
left: 50%;
transform: translateX(-50%);
.size(@w: 0, @h: 0);
border-top: 18px solid #ddd;
border-right: 18px solid transparent;
border-bottom: 18px solid transparent;
border-left: 18px solid transparent;
content: "";
}
}
}
}
}
}

View File

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

View File

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

View File

@@ -26,7 +26,7 @@ export default function RecommendedShowsContents({
thumbnailUrl,
}) {
useEffect(() => {
const containerId = "containerId-" + index;
const containerId = "recommendedShowsContentsId-" + index;
const container = document.getElementById(containerId);
if (container) {
@@ -44,8 +44,8 @@ export default function RecommendedShowsContents({
return (
<Container
className={css.container}
id={"containerId-" + index}
spotlightId={"containerId-" + index}
id={"recommendedShowsContentsId-" + index}
spotlightId={"recommendedShowsContentsId-" + index}
>
<TItemCard
imageAlt={showNm}