[SearchPanel] 리팩토링 및 컴포넌트화
This commit is contained in:
@@ -24,19 +24,7 @@ export default function SearchPanel() {
|
||||
const recommandedKeywords = useSelector(
|
||||
(state) => state.myPage.recommandedKeywordData.data?.keywords
|
||||
);
|
||||
const { searchDatas: searchDatas, totalCount: totalCount } = useSelector(
|
||||
(state) => state.search
|
||||
);
|
||||
const {
|
||||
theme: themeDatas,
|
||||
show: showDatas,
|
||||
item: itemDatas,
|
||||
} = searchDatas || {};
|
||||
const {
|
||||
theme: themeCount,
|
||||
show: showCount,
|
||||
item: itemCount,
|
||||
} = totalCount || {};
|
||||
const { searchDatas: searchDatas } = useSelector((state) => state.search);
|
||||
|
||||
const searchPerformed = useSelector((state) => state.search.searchPerformed);
|
||||
|
||||
@@ -90,10 +78,6 @@ export default function SearchPanel() {
|
||||
} else {
|
||||
dispatch(resetSearch());
|
||||
}
|
||||
|
||||
setContainerLastFocusedElement(null, ["searchResultsItemBox"]);
|
||||
setContainerLastFocusedElement(null, ["searchResultsShowBox"]);
|
||||
setContainerLastFocusedElement(null, ["searchResultsThemeBox"]);
|
||||
},
|
||||
[dispatch, searchQuery]
|
||||
);
|
||||
@@ -126,15 +110,7 @@ export default function SearchPanel() {
|
||||
/>
|
||||
{searchPerformed ? (
|
||||
Object.keys(searchDatas).length > 0 ? (
|
||||
<SearchResults
|
||||
themeDatas={themeDatas}
|
||||
itemDatas={itemDatas}
|
||||
showDatas={showDatas}
|
||||
themeCount={themeCount}
|
||||
showCount={showCount}
|
||||
itemCount={itemCount}
|
||||
query={searchQuery}
|
||||
/>
|
||||
<SearchResults />
|
||||
) : (
|
||||
<NoSearchResults />
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@import "../../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../../style/utils.module.less";
|
||||
@import "../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../style/utils.module.less";
|
||||
|
||||
.card {
|
||||
.size(@w: 561px, @h:150px);
|
||||
@@ -2,7 +2,7 @@ import React, { memo } from "react";
|
||||
|
||||
import Spottable from "@enact/spotlight/Spottable";
|
||||
|
||||
import IcLiveShow from "../../../../../../assets/images/tag/tag-liveshow.svg";
|
||||
import IcLiveShow from "../../../../../assets/images/tag/tag-liveshow.svg";
|
||||
import css from "./SearchShowCard.module.less";
|
||||
|
||||
const CardContainer = Spottable("div");
|
||||
@@ -1,5 +1,5 @@
|
||||
@import "../../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../../style/utils.module.less";
|
||||
@import "../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../style/utils.module.less";
|
||||
|
||||
.card {
|
||||
.size(@w: 344px, @h: 281px);
|
||||
@@ -1,9 +1,9 @@
|
||||
@import "../../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../../style/utils.module.less";
|
||||
@import "../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../style/utils.module.less";
|
||||
|
||||
.card {
|
||||
.size(@w: 560px, @h: 140px);
|
||||
background-image: url("../../../../../../assets/images/searchpanel/bg_srch_curation.png");
|
||||
background-image: url("../../../../../assets/images/searchpanel/bg_srch_curation.png");
|
||||
border: 2px solid #ccc;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
@@ -1,46 +0,0 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
|
||||
import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
|
||||
import useScrollTo from "../../../../hooks/useScrollTo";
|
||||
import { SEARCH_DATA_MAX_RESULTS_LIMIT } from "../../../../utils/Config";
|
||||
import SearchItemCard from "./SearchItemCard/SearchItemCard";
|
||||
import css from "./SearchItemResults.module.less";
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ leaveFor: { right: "" }, enterTo: "last-focused" },
|
||||
"div"
|
||||
);
|
||||
|
||||
export default function SearchItemResults({ itemDatas, itemCount, ...rest }) {
|
||||
delete rest.query;
|
||||
|
||||
const { getScrollTo, scrollLeft } = useScrollTo();
|
||||
|
||||
useEffect(() => {
|
||||
if (itemDatas.length <= SEARCH_DATA_MAX_RESULTS_LIMIT) {
|
||||
scrollLeft();
|
||||
}
|
||||
}, [itemDatas]);
|
||||
|
||||
return (
|
||||
<Container className={css.container}>
|
||||
{itemDatas && (
|
||||
<></>
|
||||
// <TVirtualGridList
|
||||
// spotlightId="searchResultsItemBox"
|
||||
// cbScrollTo={getScrollTo}
|
||||
// className={css.grid}
|
||||
// items={itemDatas}
|
||||
// dataSize={itemDatas.length}
|
||||
// direction="horizontal"
|
||||
// itemCard={SearchItemCard}
|
||||
// itemWidth={561}
|
||||
// itemHeight={150}
|
||||
// spacing={30}
|
||||
// />
|
||||
)}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
@import "../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../style/utils.module.less";
|
||||
|
||||
.container {
|
||||
.flex();
|
||||
margin: 30px 0 50px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.grid {
|
||||
height: 150px;
|
||||
}
|
||||
@@ -1,52 +1,57 @@
|
||||
import React from "react";
|
||||
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
|
||||
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
|
||||
import { $L } from "../../../utils/helperMethods";
|
||||
import SearchItemResults from "./SearchItemResults/SearchItemResults";
|
||||
import css from "./SearchResults.module.less";
|
||||
import SearchShowResults from "./SearchShowResults/SearchShowResults";
|
||||
import SearchThemeResults from "./SearchThemeResults/SearchThemeResults";
|
||||
import SearchResultsType from "./SearchResultsType";
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ enterTo: "last-focused" },
|
||||
"div"
|
||||
);
|
||||
|
||||
export default function SearchResults({
|
||||
themeDatas,
|
||||
itemDatas,
|
||||
showDatas,
|
||||
themeCount,
|
||||
itemCount,
|
||||
showCount,
|
||||
query,
|
||||
}) {
|
||||
export default function SearchResults() {
|
||||
const searchDatas = useSelector((state) => state.search.searchDatas) || {};
|
||||
const totalCount = useSelector((state) => state.search.totalCount) || {};
|
||||
|
||||
const results = Object.entries(searchDatas).reduce((acc, [key, data]) => {
|
||||
if (!data) return acc;
|
||||
|
||||
const titleMap = {
|
||||
theme: $L("Hot Picks"),
|
||||
show: $L("Shows"),
|
||||
item: $L("Items"),
|
||||
};
|
||||
|
||||
const item = {
|
||||
title: titleMap[key],
|
||||
category: key,
|
||||
data,
|
||||
};
|
||||
|
||||
if (key !== "theme") {
|
||||
item.count = totalCount[key];
|
||||
}
|
||||
|
||||
acc.push(item);
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Container className={css.container}>
|
||||
{themeDatas && (
|
||||
<>
|
||||
<SectionTitle title={$L("Hot Picks")} />
|
||||
<SearchThemeResults themeDatas={themeDatas} themeCount={themeCount} />
|
||||
</>
|
||||
)}
|
||||
{showDatas && (
|
||||
<>
|
||||
<SectionTitle title={$L("Shows")} itemCount={showCount} />
|
||||
<SearchShowResults showDatas={showDatas} showCount={showCount} />
|
||||
</>
|
||||
)}
|
||||
{itemDatas && (
|
||||
<>
|
||||
<SectionTitle title={$L("Items")} itemCount={itemCount} />
|
||||
<SearchItemResults
|
||||
itemDatas={itemDatas}
|
||||
itemCount={itemCount}
|
||||
query={query}
|
||||
{results &&
|
||||
results.map(({ title, category, data, count }, index) => (
|
||||
<SearchResultsType
|
||||
key={index}
|
||||
title={title}
|
||||
data={data}
|
||||
count={count}
|
||||
category={category}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
))}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
import React, { useCallback, useEffect } from "react";
|
||||
|
||||
import classNames from "classnames";
|
||||
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
|
||||
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
|
||||
import TVirtualGridList from "../../../components/TVirtualGridList/TVirtualGridList";
|
||||
import useScrollTo from "../../../hooks/useScrollTo";
|
||||
import { SEARCH_DATA_MAX_RESULTS_LIMIT } from "../../../utils/Config";
|
||||
import SearchItemCard from "./SearchCard/SearchItemCard";
|
||||
import SearchShowCard from "./SearchCard/SearchShowCard";
|
||||
import SearchThemeCard from "./SearchCard/SearchThemeCard";
|
||||
import css from "./SearchResultsType.module.less";
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ leaveFor: { right: "" }, enterTo: "last-focused" },
|
||||
"div"
|
||||
);
|
||||
|
||||
const ITEM_SIZE = {
|
||||
theme: {
|
||||
itemWidth: 560,
|
||||
itemHeight: 130,
|
||||
spacing: 30,
|
||||
},
|
||||
|
||||
show: {
|
||||
itemWidth: 344,
|
||||
itemHeight: 281,
|
||||
spacing: 0,
|
||||
},
|
||||
|
||||
item: {
|
||||
itemWidth: 561,
|
||||
itemHeight: 150,
|
||||
spacing: 30,
|
||||
},
|
||||
};
|
||||
|
||||
export default function SearchResultsType({ title, data, count, category }) {
|
||||
const { getScrollTo, scrollLeft } = useScrollTo();
|
||||
|
||||
useEffect(() => {
|
||||
if (data.length <= SEARCH_DATA_MAX_RESULTS_LIMIT) {
|
||||
scrollLeft();
|
||||
}
|
||||
}, [data]);
|
||||
|
||||
const renderItem = useCallback(
|
||||
({ index, ...rest }) => {
|
||||
switch (category) {
|
||||
case "theme": {
|
||||
const {
|
||||
contentId,
|
||||
endTime,
|
||||
keyword,
|
||||
partnerLogo,
|
||||
partnerName,
|
||||
startTime,
|
||||
title,
|
||||
} = data[index];
|
||||
|
||||
return <SearchThemeCard title={title} keyword={keyword} {...rest} />;
|
||||
}
|
||||
|
||||
case "show": {
|
||||
const {
|
||||
contentId,
|
||||
endTime,
|
||||
liveFlag,
|
||||
partnerId,
|
||||
partnerLogo,
|
||||
partnerName,
|
||||
startTime,
|
||||
thumbnail,
|
||||
title,
|
||||
} = data[index];
|
||||
|
||||
return (
|
||||
<SearchShowCard
|
||||
liveFlag={liveFlag}
|
||||
thumbnail={thumbnail}
|
||||
title={title}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
case "item": {
|
||||
const {
|
||||
contentId,
|
||||
dcPrice,
|
||||
partnerLogo,
|
||||
partnerName,
|
||||
price,
|
||||
reviewGrade,
|
||||
soldout,
|
||||
thumbnail,
|
||||
title,
|
||||
} = data[index];
|
||||
|
||||
return (
|
||||
<SearchItemCard
|
||||
thumbnail={thumbnail}
|
||||
title={title}
|
||||
price={price}
|
||||
dcPrice={dcPrice}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
},
|
||||
[data, category]
|
||||
);
|
||||
|
||||
const { itemWidth, itemHeight, spacing } = ITEM_SIZE[category] || {};
|
||||
|
||||
return (
|
||||
<>
|
||||
<SectionTitle title={title} itemCount={count ? count : null} />
|
||||
<Container
|
||||
className={classNames(css.container, category && css[category])}
|
||||
>
|
||||
<TVirtualGridList
|
||||
cbScrollTo={getScrollTo}
|
||||
className={css.grid}
|
||||
dataSize={data.length}
|
||||
renderItem={renderItem}
|
||||
direction="horizontal"
|
||||
itemWidth={itemWidth}
|
||||
itemHeight={itemHeight}
|
||||
spacing={spacing}
|
||||
/>
|
||||
</Container>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
@import "../../../style/CommonStyle.module.less";
|
||||
@import "../../../style/utils.module.less";
|
||||
|
||||
.container {
|
||||
.flex();
|
||||
margin: 30px 0 50px;
|
||||
width: 100%;
|
||||
|
||||
&.theme {
|
||||
.grid {
|
||||
height: 141px;
|
||||
}
|
||||
}
|
||||
|
||||
&.show {
|
||||
.grid {
|
||||
height: 281px;
|
||||
}
|
||||
}
|
||||
|
||||
&.item {
|
||||
.grid {
|
||||
height: 150px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
import React, { useEffect } from "react";
|
||||
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
|
||||
import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
|
||||
import useScrollTo from "../../../../hooks/useScrollTo";
|
||||
import { SEARCH_DATA_MAX_RESULTS_LIMIT } from "../../../../utils/Config";
|
||||
import SearchShowCard from "./SearchShowCard/SearchShowCard";
|
||||
import css from "./SearchShowResults.module.less";
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ leaveFor: { right: "" }, enterTo: "last-focused" },
|
||||
"div"
|
||||
);
|
||||
|
||||
export default function SearchShowResults({ showDatas, showCount, ...rest }) {
|
||||
delete rest.query;
|
||||
|
||||
const { getScrollTo, scrollLeft } = useScrollTo();
|
||||
|
||||
useEffect(() => {
|
||||
if (showDatas.length <= SEARCH_DATA_MAX_RESULTS_LIMIT) {
|
||||
scrollLeft();
|
||||
}
|
||||
}, [showDatas]);
|
||||
|
||||
return (
|
||||
<Container className={css.container}>
|
||||
{showDatas && (
|
||||
<></>
|
||||
// <TVirtualGridList
|
||||
// spotlightId="searchResultsShowBox"
|
||||
// className={css.grid}
|
||||
// cbScrollTo={getScrollTo}
|
||||
// items={showDatas}
|
||||
// dataSize={showDatas.length}
|
||||
// direction="horizontal"
|
||||
// itemCard={SearchShowCard}
|
||||
// itemWidth={344}
|
||||
// itemHeight={281}
|
||||
// spacing={0}
|
||||
// />
|
||||
)}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
@import "../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../style/utils.module.less";
|
||||
|
||||
.container {
|
||||
.flex();
|
||||
margin: 30px 0 50px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.grid {
|
||||
height: 281px;
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
import React, { useEffect } from "react";
|
||||
|
||||
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
|
||||
|
||||
import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
|
||||
import useScrollTo from "../../../../hooks/useScrollTo";
|
||||
import { SEARCH_DATA_MAX_RESULTS_LIMIT } from "../../../../utils/Config";
|
||||
import SearchThemeCard from "./SearchThemeCard/SearchThemeCard";
|
||||
import css from "./SearchThemeResults.module.less";
|
||||
|
||||
const Container = SpotlightContainerDecorator(
|
||||
{ leaveFor: { right: "" }, enterTo: "last-focused" },
|
||||
"div"
|
||||
);
|
||||
|
||||
export default function SearchThemeResults({
|
||||
themeDatas,
|
||||
themeCount,
|
||||
...rest
|
||||
}) {
|
||||
delete rest.query;
|
||||
|
||||
const { getScrollTo, scrollLeft } = useScrollTo();
|
||||
|
||||
useEffect(() => {
|
||||
if (themeDatas.length <= SEARCH_DATA_MAX_RESULTS_LIMIT) {
|
||||
scrollLeft();
|
||||
}
|
||||
}, [themeDatas]);
|
||||
|
||||
return (
|
||||
<Container className={css.container}>
|
||||
{themeDatas && (
|
||||
<></>
|
||||
// <TVirtualGridList
|
||||
// spotlightId="searchResultsThemeBox"
|
||||
// className={css.grid}
|
||||
// items={themeDatas}
|
||||
// cbScrollTo={getScrollTo}
|
||||
// dataSize={themeDatas.length}
|
||||
// direction="horizontal"
|
||||
// itemCard={SearchThemeCard}
|
||||
// itemWidth={560}
|
||||
// itemHeight={130}
|
||||
// spacing={30}
|
||||
// />
|
||||
)}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
@import "../../../../style/CommonStyle.module.less";
|
||||
@import "../../../../style/utils.module.less";
|
||||
|
||||
.container {
|
||||
.flex();
|
||||
margin: 30px 0 50px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.grid {
|
||||
height: 141px;
|
||||
}
|
||||
Reference in New Issue
Block a user