131 lines
3.7 KiB
JavaScript
131 lines
3.7 KiB
JavaScript
import React, { useCallback, useEffect, useState } from "react";
|
|
|
|
import { useDispatch, useSelector } from "react-redux";
|
|
|
|
import Spotlight from "@enact/spotlight";
|
|
|
|
import { getSearch, resetSearch } from "../../actions/searchActions";
|
|
import TBody from "../../components/TBody/TBody";
|
|
import TInput, { ICONS, KINDS } from "../../components/TInput/TInput";
|
|
import TPanel from "../../components/TPanel/TPanel";
|
|
import NoSearchResults from "./NoSearchResults/NoSearchResults";
|
|
import RecommendedKeywords from "./RecommendedKeywords/RecommendedKeywords";
|
|
import css from "./SearchPanel.module.less";
|
|
import SearchResults from "./SearchResults/SearchResults";
|
|
|
|
const ITEMS_PER_PAGE = 9;
|
|
|
|
export default function SearchPanel() {
|
|
const dispatch = useDispatch();
|
|
|
|
const recommandedKeywords = useSelector(
|
|
(state) => state.myPage.recommandedKeywordData.data?.keywords
|
|
);
|
|
const searchDatas = useSelector(
|
|
(state) => state.search.searchDatas.data?.result.results
|
|
);
|
|
const searchPerformed = useSelector((state) => state.search.searchPerformed);
|
|
|
|
const [currentPage, setCurrentPage] = useState(1);
|
|
const [paginatedKeywords, setPaginatedKeywords] = useState([]);
|
|
const [pageChanged, setPageChanged] = useState(false);
|
|
|
|
const [searchQuery, setSearchQuery] = useState("");
|
|
|
|
useEffect(() => {
|
|
dispatch(resetSearch());
|
|
}, [dispatch]);
|
|
|
|
useEffect(() => {
|
|
if (recommandedKeywords) {
|
|
const startIndex = (currentPage - 1) * ITEMS_PER_PAGE;
|
|
const endIndex = startIndex + ITEMS_PER_PAGE;
|
|
|
|
setPaginatedKeywords(recommandedKeywords.slice(startIndex, endIndex));
|
|
}
|
|
}, [recommandedKeywords, currentPage]);
|
|
|
|
useEffect(() => {
|
|
if (pageChanged && paginatedKeywords.length > 0) {
|
|
const firstButtonSpotlightId = "first-keyword-button";
|
|
|
|
Spotlight.focus(firstButtonSpotlightId);
|
|
|
|
setPageChanged(false);
|
|
}
|
|
}, [pageChanged, paginatedKeywords]);
|
|
|
|
const handleSearchChange = useCallback((e) => {
|
|
const query = e.value;
|
|
|
|
if (query.length <= 255) {
|
|
setSearchQuery(query);
|
|
}
|
|
}, []);
|
|
|
|
const handleSearchSubmit = useCallback(
|
|
(query) => {
|
|
if (query.trim()) {
|
|
dispatch(
|
|
getSearch({
|
|
service: "com.lgshop.app",
|
|
query: query,
|
|
startIndex: 1,
|
|
maxResults: 10,
|
|
domain: "theme,show,item",
|
|
})
|
|
);
|
|
} else {
|
|
dispatch(resetSearch());
|
|
}
|
|
},
|
|
[dispatch, searchQuery]
|
|
);
|
|
|
|
const handleNext = useCallback(() => {
|
|
setCurrentPage((prev) => prev + 1);
|
|
setPageChanged(true);
|
|
}, [currentPage]);
|
|
|
|
const handlePrev = useCallback(() => {
|
|
setCurrentPage((prev) => (prev > 1 ? prev - 1 : prev));
|
|
setPageChanged(true);
|
|
}, [currentPage]);
|
|
|
|
const hasPrevPage = currentPage > 1;
|
|
const hasNextPage =
|
|
currentPage * ITEMS_PER_PAGE < recommandedKeywords?.length;
|
|
|
|
return (
|
|
<TPanel className={css.container}>
|
|
<TBody className={css.tBody}>
|
|
<TInput
|
|
className={css.input}
|
|
autoFocus
|
|
kind={KINDS.withIcon}
|
|
icon={ICONS.search}
|
|
value={searchQuery}
|
|
onChange={handleSearchChange}
|
|
onIconClick={() => handleSearchSubmit(searchQuery)}
|
|
/>
|
|
{searchPerformed ? (
|
|
searchDatas && searchDatas.length > 0 ? (
|
|
<SearchResults contents={searchDatas} />
|
|
) : (
|
|
<NoSearchResults />
|
|
)
|
|
) : (
|
|
<RecommendedKeywords
|
|
keywords={paginatedKeywords}
|
|
onPrev={handlePrev}
|
|
onNext={handleNext}
|
|
hasPrevPage={hasPrevPage}
|
|
hasNextPage={hasNextPage}
|
|
handleSearchSubmit={handleSearchSubmit}
|
|
/>
|
|
)}
|
|
</TBody>
|
|
</TPanel>
|
|
);
|
|
}
|