searchPanel 검색 후 ui 업데이트 로직 변경 / reducer, action 함수 수정
This commit is contained in:
@@ -1,33 +1,53 @@
|
|||||||
import { URLS } from "../api/apiConfig";
|
import { URLS } from "../api/apiConfig";
|
||||||
import { TAxios } from "../api/TAxios";
|
import { TAxios } from "../api/TAxios";
|
||||||
|
import { SEARCH_DATA_MAX_RESULTS_LIMIT } from "../utils/Config";
|
||||||
import { types } from "./actionTypes";
|
import { types } from "./actionTypes";
|
||||||
|
|
||||||
// Search 통합검색 (IBS) 데이터 조회 IF-LGSP-090
|
// Search 통합검색 (IBS) 데이터 조회 IF-LGSP-090
|
||||||
export const getSearch = (params) => (dispatch, getState) => {
|
let getSearchKey = null;
|
||||||
const { service, query, startIndex, maxResults, domain } = params;
|
export const getSearch =
|
||||||
|
(params, startIndex = 1, key) =>
|
||||||
|
(dispatch, getState) => {
|
||||||
|
const { service, query, domain } = params;
|
||||||
|
const maxResults = SEARCH_DATA_MAX_RESULTS_LIMIT;
|
||||||
|
|
||||||
|
let currentKey = key;
|
||||||
const onSuccess = (response) => {
|
const onSuccess = (response) => {
|
||||||
console.log("getSearch onSuccess: ", response.data);
|
console.log("getSearch onSuccess: ", response.data);
|
||||||
|
|
||||||
|
if (startIndex === 1) {
|
||||||
|
getSearchKey = new Date();
|
||||||
|
currentKey = getSearchKey;
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: types.GET_SEARCH,
|
type: types.GET_SEARCH,
|
||||||
payload: response.data,
|
payload: response.data,
|
||||||
});
|
});
|
||||||
|
} else if (getSearchKey === currentKey) {
|
||||||
|
dispatch({
|
||||||
|
type: types.GET_SEARCH,
|
||||||
|
payload: response.data,
|
||||||
|
append: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const processedData = response.data.data.result.results.reduce(
|
const stateBeforeLoop = getState();
|
||||||
(acc, current) => {
|
const nextStartIndex = response.data.data.result.results.reduce(
|
||||||
acc.data[current.type] = current.docs;
|
(acc, category) => {
|
||||||
acc.totalCount[current.type] = current.total_count;
|
const { type, total_count } = category;
|
||||||
|
const fetchedCount =
|
||||||
|
stateBeforeLoop.search.searchDatas[type]?.length ||
|
||||||
|
0 + category.docs.length;
|
||||||
|
const remainingData = total_count - fetchedCount;
|
||||||
|
|
||||||
return acc;
|
return remainingData > 0 ? Math.max(acc, fetchedCount + 1) : acc;
|
||||||
},
|
},
|
||||||
{ data: {}, totalCount: {} }
|
startIndex
|
||||||
);
|
);
|
||||||
|
|
||||||
dispatch({
|
if (nextStartIndex > startIndex) {
|
||||||
type: types.GET_SEARCH_PROCESSED,
|
dispatch(getSearch(params, nextStartIndex, currentKey));
|
||||||
payload: processedData,
|
}
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onFail = (error) => {
|
const onFail = (error) => {
|
||||||
@@ -44,7 +64,7 @@ export const getSearch = (params) => (dispatch, getState) => {
|
|||||||
onSuccess,
|
onSuccess,
|
||||||
onFail
|
onFail
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const resetSearch = (status) => ({
|
export const resetSearch = (status) => ({
|
||||||
type: types.RESET_SEARCH,
|
type: types.RESET_SEARCH,
|
||||||
|
|||||||
@@ -2,28 +2,35 @@ import { types } from "../actions/actionTypes";
|
|||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
searchDatas: {},
|
searchDatas: {},
|
||||||
processedDatas: {
|
|
||||||
data: {},
|
|
||||||
totalCount: {},
|
totalCount: {},
|
||||||
},
|
|
||||||
searchPerformed: false,
|
searchPerformed: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const searchReducer = (state = initialState, action) => {
|
export const searchReducer = (state = initialState, action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case types.GET_SEARCH:
|
case types.GET_SEARCH: {
|
||||||
return {
|
const newResults = action.payload.data.result.results;
|
||||||
...state,
|
|
||||||
searchDatas: action.payload,
|
const updatedSearchDatas = action.append ? { ...state.searchDatas } : {};
|
||||||
searchPerformed: true,
|
newResults.forEach(({ type, docs }) => {
|
||||||
};
|
updatedSearchDatas[type] =
|
||||||
|
action.append && updatedSearchDatas[type]
|
||||||
|
? updatedSearchDatas[type].concat(docs)
|
||||||
|
: docs;
|
||||||
|
});
|
||||||
|
|
||||||
|
const updatedTotalCount = action.append ? { ...state.totalCount } : {};
|
||||||
|
newResults.forEach(({ type, total_count }) => {
|
||||||
|
updatedTotalCount[type] = total_count;
|
||||||
|
});
|
||||||
|
|
||||||
case types.GET_SEARCH_PROCESSED:
|
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
processedDatas: action.payload,
|
searchDatas: updatedSearchDatas,
|
||||||
|
totalCount: updatedTotalCount,
|
||||||
searchPerformed: true,
|
searchPerformed: true,
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
case types.RESET_SEARCH:
|
case types.RESET_SEARCH:
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -29,3 +29,6 @@ export const panel_names = {
|
|||||||
|
|
||||||
//button
|
//button
|
||||||
export const TBUTTON_PRESS_DELAY = 100;
|
export const TBUTTON_PRESS_DELAY = 100;
|
||||||
|
|
||||||
|
//search data
|
||||||
|
export const SEARCH_DATA_MAX_RESULTS_LIMIT = 30;
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ export default function NoSearchResults() {
|
|||||||
return (
|
return (
|
||||||
<div className={css.container}>
|
<div className={css.container}>
|
||||||
<div className={css.info}>
|
<div className={css.info}>
|
||||||
|
<div className={css.imageBox}>
|
||||||
<img src={NoSearchResultsImage} alt="No Datas" />
|
<img src={NoSearchResultsImage} alt="No Datas" />
|
||||||
|
</div>
|
||||||
<p>{$L("SORRY, NO RESULTS MATCHING YOUR SEARCH")}</p>
|
<p>{$L("SORRY, NO RESULTS MATCHING YOUR SEARCH")}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className={css.bestSellerWrap}>
|
<div className={css.bestSellerWrap}>
|
||||||
|
|||||||
@@ -7,6 +7,17 @@
|
|||||||
.info {
|
.info {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
|
.imageBox {
|
||||||
|
.size(@w: 360px, @h: 180px);
|
||||||
|
margin: 0 auto;
|
||||||
|
background-size: cover;
|
||||||
|
|
||||||
|
> img {
|
||||||
|
object-fit: cover;
|
||||||
|
.size(@w: 100%, @h: 100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
> p {
|
> p {
|
||||||
.font (@fontFamily: @baseFontBold, @fontSize: 36px);
|
.font (@fontFamily: @baseFontBold, @fontSize: 36px);
|
||||||
color: #a3a3a3;
|
color: #a3a3a3;
|
||||||
|
|||||||
@@ -21,19 +21,20 @@ export default function SearchPanel() {
|
|||||||
const recommandedKeywords = useSelector(
|
const recommandedKeywords = useSelector(
|
||||||
(state) => state.myPage.recommandedKeywordData.data?.keywords
|
(state) => state.myPage.recommandedKeywordData.data?.keywords
|
||||||
);
|
);
|
||||||
const searchDatas = useSelector(
|
const { searchDatas: searchDatas, totalCount: totalCount } = useSelector(
|
||||||
(state) => state.search.searchDatas.data?.result.results
|
(state) => state.search
|
||||||
);
|
);
|
||||||
const {
|
const {
|
||||||
theme: themeDatas,
|
theme: themeDatas,
|
||||||
show: showDatas,
|
show: showDatas,
|
||||||
item: itemDatas,
|
item: itemDatas,
|
||||||
} = useSelector((state) => state.search.processedDatas.data);
|
} = searchDatas || {};
|
||||||
const {
|
const {
|
||||||
theme: themeCount,
|
theme: themeCount,
|
||||||
show: showCount,
|
show: showCount,
|
||||||
item: itemCount,
|
item: itemCount,
|
||||||
} = useSelector((state) => state.search.processedDatas.totalCount);
|
} = totalCount || {};
|
||||||
|
|
||||||
const searchPerformed = useSelector((state) => state.search.searchPerformed);
|
const searchPerformed = useSelector((state) => state.search.searchPerformed);
|
||||||
|
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
@@ -80,8 +81,6 @@ export default function SearchPanel() {
|
|||||||
getSearch({
|
getSearch({
|
||||||
service: "com.lgshop.app",
|
service: "com.lgshop.app",
|
||||||
query: query,
|
query: query,
|
||||||
startIndex: 1,
|
|
||||||
maxResults: 10,
|
|
||||||
domain: "theme,show,item",
|
domain: "theme,show,item",
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -119,7 +118,7 @@ export default function SearchPanel() {
|
|||||||
onIconClick={() => handleSearchSubmit(searchQuery)}
|
onIconClick={() => handleSearchSubmit(searchQuery)}
|
||||||
/>
|
/>
|
||||||
{searchPerformed ? (
|
{searchPerformed ? (
|
||||||
searchDatas && searchDatas.length > 0 ? (
|
(searchDatas && themeDatas) || showDatas || itemDatas ? (
|
||||||
<SearchResults
|
<SearchResults
|
||||||
themeDatas={themeDatas}
|
themeDatas={themeDatas}
|
||||||
itemDatas={itemDatas}
|
itemDatas={itemDatas}
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ export default function SearchItemResults({ itemDatas, itemCount, ...rest }) {
|
|||||||
scrollMode="translate"
|
scrollMode="translate"
|
||||||
horizontalScrollbar="hidden"
|
horizontalScrollbar="hidden"
|
||||||
noScrollByWheel
|
noScrollByWheel
|
||||||
// onScrollStop={handleScrollStop}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Container>
|
</Container>
|
||||||
|
|||||||
Reference in New Issue
Block a user