Skip to content

Commit

Permalink
Feat: 검색 필터링 조건 및 검색어 쿼리 스트링 값으로 반영하여 검색 결과 유지, useSearchPageParams 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
rmdnps10 committed Apr 19, 2024
1 parent 93f467d commit 14ee167
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 41 deletions.
11 changes: 11 additions & 0 deletions src/components/Buyer/Common/OpenConsultSortModal.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ReactComponent as CheckIcon } from 'assets/icons/icon-modal-check.svg';
import { SetStateAction } from 'react';
import { SetURLSearchParams } from 'react-router-dom';
import { useRecoilState, useSetRecoilState } from 'recoil';
import styled, { keyframes } from 'styled-components';
import { Green, Grey1, Grey4, Grey6 } from 'styles/color';
Expand All @@ -9,12 +10,16 @@ interface SortModalProps {
sortType: number;
setSortType: React.Dispatch<SetStateAction<number>>;
setPostId: React.Dispatch<SetStateAction<number>>;
searchParams: URLSearchParams;
setSearchParams: SetURLSearchParams;
}
//최근순 인기순 별점순 모달
export const OpenConsultSortModal = ({
sortType,
setSortType,
setPostId,
searchParams,
setSearchParams,
}: SortModalProps) => {
//modal 여부
const [isModalOpen, setIsModalOpen] = useRecoilState(isSortModalOpenState);
Expand All @@ -31,6 +36,8 @@ export const OpenConsultSortModal = ({
onClick={() => {
setSortType(0);
setPostId(0);
searchParams.set('open-sort', 'recent');
setSearchParams(searchParams);
setIsModalOpen(false);
setScrollLock(false);
}}
Expand All @@ -49,6 +56,8 @@ export const OpenConsultSortModal = ({
onClick={() => {
setSortType(1);
setPostId(0);
searchParams.set('open-sort', 'likes');
setSearchParams(searchParams);
setIsModalOpen(false);
setScrollLock(false);
}}
Expand All @@ -67,6 +76,8 @@ export const OpenConsultSortModal = ({
onClick={() => {
setSortType(2);
setPostId(0);
searchParams.set('open-sort', 'comments');
setSearchParams(searchParams);
setIsModalOpen(false);
setScrollLock(false);
}}
Expand Down
11 changes: 11 additions & 0 deletions src/components/Buyer/Common/SortModal.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ReactComponent as CheckIcon } from 'assets/icons/icon-modal-check.svg';
import { SetStateAction } from 'react';
import { SetURLSearchParams } from 'react-router-dom';
import { useRecoilState, useSetRecoilState } from 'recoil';
import styled, { keyframes } from 'styled-components';
import { Green, Grey1, Grey4, Grey6 } from 'styles/color';
Expand All @@ -9,12 +10,16 @@ interface SortModalProps {
sortType: number;
setSortType: React.Dispatch<SetStateAction<number>>;
setPageNum: React.Dispatch<SetStateAction<number>>;
searchParams: URLSearchParams;
setSearchParams: SetURLSearchParams;
}
//최근순 인기순 별점순 모달
export const SortModal = ({
sortType,
setSortType,
setPageNum,
searchParams,
setSearchParams,
}: SortModalProps) => {
//modal 여부
const [isModalOpen, setIsModalOpen] = useRecoilState(isSortModalOpenState);
Expand All @@ -32,6 +37,8 @@ export const SortModal = ({
setSortType(0);
setPageNum(0);
setIsModalOpen(false);
searchParams.set('sort', 'recent');
setSearchParams(searchParams);
setScrollLock(false);
}}
>
Expand All @@ -49,6 +56,8 @@ export const SortModal = ({
onClick={() => {
setSortType(1);
setPageNum(0);
searchParams.set('sort', 'popular');
setSearchParams(searchParams);
setIsModalOpen(false);
setScrollLock(false);
}}
Expand All @@ -67,6 +76,8 @@ export const SortModal = ({
onClick={() => {
setSortType(2);
setPageNum(0);
searchParams.set('sort', 'rating');
setSearchParams(searchParams);
setIsModalOpen(false);
setScrollLock(false);
}}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Common/Divider2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { ReactComponent as UnderLineBuyerBig } from 'assets/icons/underline-big.
import { Subtitle } from 'styles/font';
interface Divder2Props {
tabState: number;
setTabState: React.Dispatch<React.SetStateAction<number>>;
setTabState: (tabState: number) => void;
}
function Divider2({ tabState, setTabState }: Divder2Props) {
return (
Expand Down
78 changes: 78 additions & 0 deletions src/hooks/useSearchPageParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { ChangeEvent, useCallback, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import { useRecoilValue } from 'recoil';
import { searchKeywordState } from 'utils/atom';

export const useSearchPageParams = () => {
const [searchParams, setSearchParams] = useSearchParams();
const keywordParam = searchParams.get('keyword');
const typeParam = searchParams.get('searchType');
const sortParam = searchParams.get('sort');
const openSortParam = searchParams.get('open-sort');
const keywordFromPrevPage = useRecoilValue(searchKeywordState);
const initialKeyword = keywordParam ?? keywordFromPrevPage;
const initialSearchType = typeParam ?? 'counselor';
const initialSortType =
sortParam === 'rating' ? 2 : sortParam === 'popular' ? 1 : 0;
const initialOpenSortType =
openSortParam === 'comments' ? 2 : openSortParam === 'likes' ? 1 : 0;
const initialTabState = typeParam === 'open-consult' ? 2 : 1;
const [input, setInput] = useState(keywordFromPrevPage);
const [keyword, setKeyword] = useState(initialKeyword);
const [searchType, setSearchType] = useState<string>(initialSearchType);
const [openSortType, setOpenSortType] = useState<number>(initialOpenSortType);
const [sortType, setSortType] = useState<number>(initialSortType);
const [tabState, setTabState] = useState<number>(initialTabState);
const handleClickOpenConsult = useCallback(() => {
setSearchType('open-consult');
searchParams.set('searchType', 'open-consult');
setTabState(2);
setSearchParams(searchParams);
}, []);
const handleClickCounselor = useCallback(() => {
setSearchType('counselor');
searchParams.set('searchType', 'counselor');
setSearchParams(searchParams);
setTabState(1);
console.log('hi');
}, []);

const handleClickTab = useCallback(
(tabState: number) => {
if (tabState === 1) {
handleClickCounselor();
} else {
handleClickOpenConsult();
}
},
[tabState],
);
const handleChangeInput = (event: ChangeEvent<HTMLInputElement>) => {
setInput(event.target.value);
};
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
setKeyword(input);
searchParams.set('keyword', input);
setSearchParams(searchParams);
};

return {
handleClickTab,
searchParams,
openSortType,
setOpenSortType,
setSearchParams,
input,
tabState,
setTabState,
keyword,
setKeyword,
handleSubmit,
keywordFromPrevPage,
searchType,
sortType,
setSortType,
handleChangeInput,
};
};
76 changes: 38 additions & 38 deletions src/pages/Buyer/BuyerSearchResult.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@ import { ReactComponent as Search } from 'assets/icons/search.svg';
import { ReactComponent as Down } from 'assets/icons/icon-drop-down.svg';
import { SearchResults } from 'components/Buyer/BuyerSearchResult/SearchResults';
import { SortModal } from 'components/Buyer/Common/SortModal';
import { ChangeEvent, useLayoutEffect, useRef, useState } from 'react';
import { useLayoutEffect, useRef, useState } from 'react';
import { openSortList, sortList } from 'utils/constant';
import { useRecoilState, useSetRecoilState } from 'recoil';
import {
isSortModalOpenState,
scrollLockState,
searchKeywordState,
} from 'utils/atom';
import Input from 'components/Common/Input';
import {
Expand All @@ -30,33 +29,40 @@ import OpenConsultResults from 'components/Buyer/BuyerSearchResult/OpenConsultRe
import { openConsultApiObject } from './BuyerConsult';
import { OpenConsultSortModal } from 'components/Buyer/Common/OpenConsultSortModal';
import { ConverOpenSortType } from 'utils/convertOpenSortType';
import { useSearchPageParams } from 'hooks/useSearchPageParams';
export const BuyerSearchResult = () => {
const navigate = useNavigate();
//0 : 최신순 1:인기순 2: 별점순
// 바뀔 때마다 useEffect로 request
const [sortType, setSortType] = useState<number>(0);
// Modal 여부(recoil)
// Modal 여부(recoil), 스크롤 막기
const [isModalOpen, setIsModalOpen] =
useRecoilState<boolean>(isSortModalOpenState);
//scorll 막기
const setScrollLock = useSetRecoilState(scrollLockState);
//검색된 value
const [keyword, setKeyword] = useRecoilState(searchKeywordState);
//input value
const initInput = keyword;
const [input, setInput] = useState(initInput);
//결과저장
// 검색 결과 리스트 - 상담사 리스트와 공개 상담 리스트
const [searchData, setSearchData] = useState<SearchResultData[]>([]);
const [openConsultSearchData, setOpenConsultSearchData] = useState<
openConsultApiObject[]
>([]);
//무한스크롤 위한 page num
//무한스크롤 위한 page num과 lastId
const [pageNum, setPageNum] = useState<number>(0);
const [lastId, setLastId] = useState<number>(0);
// 상담사 탭 0, 공개 상담 1
const [tabState, setTabState] = useState<number>(1);
// 무한스크롤을 trigger를 위한 상태
const [isLastElem, setIsLastElem] = useState<boolean>(false);
const preventRef = useRef(true); // 중복 방지 옵션
// 무한스크롤을 trigger를 위한 상태
const [isLoading, setIsLoading] = useState<boolean>(true);
const preventRef = useRef(true);
const {
handleClickTab,
searchParams,
setSearchParams,
openSortType,
setOpenSortType,
input,
keyword,
tabState,
handleSubmit,
sortType,
setSortType,
handleChangeInput,
} = useSearchPageParams();
const onIntersect: IntersectionObserverCallback = async (entry) => {
if (
entry[0].isIntersecting &&
Expand All @@ -74,24 +80,13 @@ export const BuyerSearchResult = () => {
preventRef.current = true;
}
};
//현재 대상 및 option을 props로 전달
const { setTarget } = useIntersectionObserver({
root: null,
rootMargin: '0px',
threshold: 0.8,
onIntersect,
});
//input onchagne
const handleOnChange = (event: ChangeEvent<HTMLInputElement>) => {
setInput(event.target.value);
};
const handleSubmit: any = (event: ChangeEvent<HTMLFormElement>) => {
event.preventDefault();
setKeyword(input);
};

//로딩 state
const [isLoading, setIsLoading] = useState<boolean>(true);
const fetchSearchResults = async (searchWord: string, pageIndex: number) => {
try {
const body = {
Expand Down Expand Up @@ -134,7 +129,7 @@ export const BuyerSearchResult = () => {
word: searchWord,
postId: postId,
};
const sortTypeString: string = ConverOpenSortType(sortType);
const sortTypeString: string = ConverOpenSortType(openSortType);
const res: any = await patchSearchWordsPostsResults(sortTypeString, body);
if (res.status === 200) {
if (res.data.length !== 0) {
Expand Down Expand Up @@ -171,7 +166,8 @@ export const BuyerSearchResult = () => {
} else if (tabState === 2) {
fetchOpenSearchResults(keyword, 0);
}
}, [keyword, sortType, tabState]);
}, [keyword, sortType, tabState, openSortType]);

if (isLoading) {
return (
<>
Expand All @@ -184,7 +180,7 @@ export const BuyerSearchResult = () => {
<FormWrapper onSubmit={handleSubmit}>
<Input
value={input}
onChange={handleOnChange}
onChange={handleChangeInput}
placeholder="상담사명, 제목, 키워드"
fontSize="1.6rem"
fontWeight="400"
Expand Down Expand Up @@ -225,7 +221,7 @@ export const BuyerSearchResult = () => {
<FormWrapper onSubmit={handleSubmit}>
<Input
value={input}
onChange={handleOnChange}
onChange={handleChangeInput}
placeholder="상담사명, 제목, 키워드"
fontSize="1.6rem"
fontWeight="400"
Expand All @@ -239,7 +235,7 @@ export const BuyerSearchResult = () => {
<SearchIcon onClick={handleSubmit} />
</FormWrapper>
</HeaderWrapper>
<Divider2 tabState={tabState} setTabState={setTabState} />
<Divider2 tabState={tabState} setTabState={handleClickTab} />
<div className="select">
<div
className="select-wrapper"
Expand Down Expand Up @@ -287,6 +283,8 @@ export const BuyerSearchResult = () => {
sortType={sortType}
setSortType={setSortType}
setPageNum={setPageNum}
searchParams={searchParams}
setSearchParams={setSearchParams}
/>
</>
) : null}
Expand All @@ -305,7 +303,7 @@ export const BuyerSearchResult = () => {
<FormWrapper onSubmit={handleSubmit}>
<Input
value={input}
onChange={handleOnChange}
onChange={handleChangeInput}
placeholder="상담사명, 제목, 키워드"
fontSize="1.6rem"
fontWeight="400"
Expand All @@ -319,7 +317,7 @@ export const BuyerSearchResult = () => {
<SearchIcon onClick={handleSubmit} />
</FormWrapper>
</HeaderWrapper>
<Divider2 tabState={tabState} setTabState={setTabState} />
<Divider2 tabState={tabState} setTabState={handleClickTab} />
<div className="select">
<div
className="select-wrapper"
Expand All @@ -328,7 +326,7 @@ export const BuyerSearchResult = () => {
setScrollLock(true);
}}
>
<Button2 color={Grey3}>{openSortList[sortType]}</Button2>
<Button2 color={Grey3}>{openSortList[openSortType]}</Button2>
<Down />
</div>
</div>
Expand Down Expand Up @@ -364,9 +362,11 @@ export const BuyerSearchResult = () => {
}}
/>
<OpenConsultSortModal
sortType={sortType}
setSortType={setSortType}
sortType={openSortType}
setSortType={setOpenSortType}
setPostId={setLastId}
searchParams={searchParams}
setSearchParams={setSearchParams}
/>
</>
) : null}
Expand Down
4 changes: 2 additions & 2 deletions src/utils/convertOpenSortType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ export const ConverOpenSortType = (typeNum: number) => {
if (typeNum === 0) {
return 'LATEST';
} else if (typeNum === 1) {
return 'DESC_TOTAL_COMMENT';
} else if (typeNum === 2) {
return 'DESC_TOTAL_LIKE';
} else if (typeNum === 2) {
return 'DESC_TOTAL_COMMENT';
} else {
return '';
}
Expand Down

0 comments on commit 14ee167

Please sign in to comment.