diff --git a/src/assets/homeIcons/search/nullImg.svg b/src/assets/homeIcons/search/nullImg.svg new file mode 100644 index 00000000..ee839bf9 --- /dev/null +++ b/src/assets/homeIcons/search/nullImg.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/Home/Onboarding/Onboarding.module.scss b/src/components/Home/Onboarding/Onboarding.module.scss index df0c03a7..5fd97b08 100644 --- a/src/components/Home/Onboarding/Onboarding.module.scss +++ b/src/components/Home/Onboarding/Onboarding.module.scss @@ -1,4 +1,4 @@ -@use "@/sass" as *; +@use '@/sass' as *; @mixin keyframes($name) { @keyframes #{$name} { diff --git a/src/components/Home/VoteAtHome/VoteCard/CardHaveVote/CardHaveVote.module.scss b/src/components/Home/VoteAtHome/VoteCard/CardHaveVote/CardHaveVote.module.scss index 9ed15ca3..2b0cbef1 100644 --- a/src/components/Home/VoteAtHome/VoteCard/CardHaveVote/CardHaveVote.module.scss +++ b/src/components/Home/VoteAtHome/VoteCard/CardHaveVote/CardHaveVote.module.scss @@ -1,4 +1,4 @@ -@use "@/sass" as *; +@use '@/sass' as *; .container { @include slide_button_container; @@ -11,11 +11,11 @@ min-height: 16.4rem; background: linear-gradient( - 119deg, - #62aaff 35.27%, - rgba(98, 170, 255, 0.3) 142.38% + 129deg, + #267dff 0.29%, + rgba(98, 170, 255, 0.95) 50.64%, + rgba(142, 255, 144, 0.88) 169.29% ); - border-radius: 1.6rem; box-sizing: border-box; diff --git a/src/components/Home/VoteAtHome/VoteCard/CardNull/CardNull.module.scss b/src/components/Home/VoteAtHome/VoteCard/CardNull/CardNull.module.scss index d8d13830..48e4b258 100644 --- a/src/components/Home/VoteAtHome/VoteCard/CardNull/CardNull.module.scss +++ b/src/components/Home/VoteAtHome/VoteCard/CardNull/CardNull.module.scss @@ -1,4 +1,4 @@ -@use "@/sass" as *; +@use '@/sass' as *; .vote_box { width: 100%; @@ -14,9 +14,10 @@ align-items: center; background: linear-gradient( - 119deg, - #62aaff 35.27%, - rgba(98, 170, 255, 0.3) 142.38% + 129deg, + #267dff 0.29%, + rgba(98, 170, 255, 0.95) 50.64%, + rgba(142, 255, 144, 0.88) 169.29% ); border-radius: 1.6rem; diff --git a/src/components/SearchFromHome/SearchBar/SearchBar.tsx b/src/components/SearchFromHome/SearchBar/SearchBar.tsx index 2fd6207a..378ff283 100644 --- a/src/components/SearchFromHome/SearchBar/SearchBar.tsx +++ b/src/components/SearchFromHome/SearchBar/SearchBar.tsx @@ -34,10 +34,9 @@ function SearchBar({forSearch, setForSearch}: PropsType) { } function search() { - const beforeData = forSearch; - beforeData.keyword = inputValue; - setForSearch(beforeData); - navigate(`/home/search?keyword=${inputValue}&category=0&map=false&location=${forSearch.location}&sort=등록순`); + navigate( + `/home/search?keyword=${inputValue}&category=0&map=false&location=${forSearch.location}&sort=등록순&hot=false`, + ); } function removeValue() { @@ -48,6 +47,7 @@ function SearchBar({forSearch, setForSearch}: PropsType) { setInputValue(''); const beforeData = forSearch; beforeData.keyword = ''; + beforeData.hot = 'false'; setForSearch(beforeData); } } diff --git a/src/components/SearchFromHome/SearchHome/HotItems/HotItem/HotItem.module.scss b/src/components/SearchFromHome/SearchHome/HotItems/HotItem/HotItem.module.scss index 8c2e3964..0121a469 100644 --- a/src/components/SearchFromHome/SearchHome/HotItems/HotItem/HotItem.module.scss +++ b/src/components/SearchFromHome/SearchHome/HotItems/HotItem/HotItem.module.scss @@ -1,4 +1,4 @@ -@use "@/sass" as *; +@use '@/sass' as *; .container { display: flex; @@ -7,9 +7,11 @@ img { min-width: 10.6rem; - min-height: 10.6rem; + height: 10.6rem; border-radius: 1.6rem; + + background-color: $neutral200; } .text_box { display: flex; diff --git a/src/components/SearchFromHome/SearchHome/HotItems/HotItem/HotItem.tsx b/src/components/SearchFromHome/SearchHome/HotItems/HotItem/HotItem.tsx index 531b6e4a..b8512538 100644 --- a/src/components/SearchFromHome/SearchHome/HotItems/HotItem/HotItem.tsx +++ b/src/components/SearchFromHome/SearchHome/HotItems/HotItem/HotItem.tsx @@ -1,25 +1,33 @@ -import { Link } from "react-router-dom"; +import {Link} from 'react-router-dom'; -import styles from "./HotItem.module.scss"; +import styles from './HotItem.module.scss'; -import areas from "@/utils/areas.json"; +import {translateCategoryToStr} from '@/hooks/Search/useSearch'; -import { SearchHotItemType } from "@/types/home"; +import nullImg from '@/assets/homeIcons/search/nullImg.svg'; +import areas from '@/utils/areas.json'; +import titleCaseChange from '@/utils/titleCaseChange'; + +import {SearchHotItemType} from '@/types/home'; interface PropsData { data: SearchHotItemType; } -function HotItem({ data }: PropsData) { - const location = areas.filter((area) => area.areaCode === data.areaCode)[0] - .name; +function HotItem({data}: PropsData) { + const location = areas.filter((area) => area.areaCode === data.areaCode)[0].name; + const category = translateCategoryToStr(data.contentTypeId); + const title = titleCaseChange(data.title); + const imgSrc = data.thumbnail ? data.thumbnail : nullImg; return ( - {`${data.title}의 + {`${data.title}의

- {data.title} - {location} + {title} + + {category} · {location} +

); diff --git a/src/components/SearchFromHome/SearchHome/HotItems/HotItems.tsx b/src/components/SearchFromHome/SearchHome/HotItems/HotItems.tsx index db7421be..f28f5d81 100644 --- a/src/components/SearchFromHome/SearchHome/HotItems/HotItems.tsx +++ b/src/components/SearchFromHome/SearchHome/HotItems/HotItems.tsx @@ -9,19 +9,19 @@ import SlideButton from '@/components/SlideButton/SlideButton'; import HotItem from './HotItem/HotItem'; -import {SearchHotItemType} from '@/types/home'; +import {Popular, SearchDataType, SearchHotItemType} from '@/types/home'; interface PropsType { type: number; } function HotItems({type}: PropsType) { - const [data, setData] = useState(); + const [data, setData] = useState(); const [slideLocation, setSlideLocation] = useState(0); const [componentRef, size] = useComponentSize(); useEffect(() => { - async function getData(apiURL: string, set: Dispatch>) { + async function getData(apiURL: string, set: Dispatch>) { try { const fetchData = await axios.get(`${apiURL}`, { params: { @@ -29,12 +29,14 @@ function HotItems({type}: PropsType) { placeTypeId: type, }, }); - set(fetchData.data); + const data: SearchDataType = fetchData.data; + + set(data.data.places); } catch (error) { console.log(error); } } - getData('api/places/popular', setData); + getData('/api/places/popular', setData); }, [type]); return (
diff --git a/src/components/SearchFromHome/SearchHome/SearchHome.tsx b/src/components/SearchFromHome/SearchHome/SearchHome.tsx index 0dcb6628..c98c1edc 100644 --- a/src/components/SearchFromHome/SearchHome/SearchHome.tsx +++ b/src/components/SearchFromHome/SearchHome/SearchHome.tsx @@ -3,16 +3,12 @@ import styles from './SearchHome.module.scss'; import HotItems from './HotItems/HotItems'; import SearchKeyword from './SearchKeyword/SearchKeyword'; -interface Propstype { - setKeywordClick: React.Dispatch>; -} - -function SearchHome({setKeywordClick}: Propstype) { +function SearchHome() { return (

인기 검색 키워드

- +

최근 30일간 인기 장소

diff --git a/src/components/SearchFromHome/SearchHome/SearchKeyword/SearchKeyword.tsx b/src/components/SearchFromHome/SearchHome/SearchKeyword/SearchKeyword.tsx index 9e28494c..dcb4b35e 100644 --- a/src/components/SearchFromHome/SearchHome/SearchKeyword/SearchKeyword.tsx +++ b/src/components/SearchFromHome/SearchHome/SearchKeyword/SearchKeyword.tsx @@ -1,4 +1,5 @@ -import {useEffect, useState} from 'react'; +import axios from 'axios'; +import {Dispatch, useEffect, useState} from 'react'; import {useNavigate} from 'react-router-dom'; import styles from './SearchKeyword.module.scss'; @@ -7,21 +8,26 @@ import useComponentSize from '@/hooks/useComponetSize'; import SlideButton from '@/components/SlideButton/SlideButton'; -import {getData} from '@/mocks/handlers/home'; +import {Keywords, SearchDataType, SearchKeywordType} from '@/types/home'; -interface Propstype { - setKeywordClick: React.Dispatch>; -} - -function SearchKeyword({setKeywordClick}: Propstype) { - const [data, setData] = useState<{name: string; code: string}[] | undefined>(); +function SearchKeyword() { + const [data, setData] = useState(); const [listWidth, setListWidth] = useState(0); const [slideLocation, setSlideLocation] = useState(0); const [componentRef, size] = useComponentSize(); const navigate = useNavigate(); useEffect(() => { - getData<{name: string; code: string}[] | undefined>('api/places/popular/keywords', setData); + async function getData(apiURL: string, set: Dispatch) { + try { + const fetchData = await axios.get(`${apiURL}`); + const data: SearchDataType = fetchData.data; + set(data.data.keywords); + } catch (error) { + console.log(error); + } + } + getData('/api/places/popular/keywords', setData); }, []); // 각 키워드의 너비를 모두 더한 값을 구함 @@ -66,11 +72,9 @@ function SearchKeyword({setKeywordClick}: Propstype) {

{ - setKeywordClick(true); - setTimeout(() => { - setKeywordClick(false); - }, 2000); - navigate(`/home/search?keyword=${keyword.name}&category=0&map=false&location=전국&sort=등록순`); + navigate( + `/home/search?keyword=${keyword.name}&category=0&map=false&location=전국&sort=등록순&hot=true`, + ); }} > {keyword.name} diff --git a/src/components/SearchFromHome/SearchList/DateFilter/DateFilter.module.scss b/src/components/SearchFromHome/SearchList/DateFilter/DateFilter.module.scss index e90ca855..8ecbb00c 100644 --- a/src/components/SearchFromHome/SearchList/DateFilter/DateFilter.module.scss +++ b/src/components/SearchFromHome/SearchList/DateFilter/DateFilter.module.scss @@ -1,6 +1,8 @@ -@use "@/sass" as *; +@use '@/sass' as *; .container { + position: relative; + width: 7.9rem; height: 2.4rem; @@ -17,4 +19,30 @@ width: 2.4rem; height: 2.4rem; } + + .modal { + position: absolute; + top: 32px; + right: 0; + + width: 10.8rem; + + display: flex; + flex-direction: column; + justify-content: space-between; + + padding: 20px 32px; + + border-radius: 16px; + + background-color: $neutral0; + + box-shadow: + 0px 1px 8px 2px rgba(20, 20, 20, 0.1), + 0px 0px 1px 0px rgba(20, 20, 20, 0.04); + + overflow: hidden; + + transition: 0.5s all; + } } diff --git a/src/components/SearchFromHome/SearchList/DateFilter/DateFilter.tsx b/src/components/SearchFromHome/SearchList/DateFilter/DateFilter.tsx index 3db7424d..e26c4bc0 100644 --- a/src/components/SearchFromHome/SearchList/DateFilter/DateFilter.tsx +++ b/src/components/SearchFromHome/SearchList/DateFilter/DateFilter.tsx @@ -1,12 +1,50 @@ -import { BsFilterLeft } from "react-icons/bs"; +import {useEffect, useState} from 'react'; +import {BsFilterLeft} from 'react-icons/bs'; +import {useNavigate} from 'react-router-dom'; -import styles from "./DateFilter.module.scss"; +import styles from './DateFilter.module.scss'; + +import {ForSearchType} from '@/types/home'; + +interface PropsType { + forSearch: ForSearchType; +} + +function DateFilter({forSearch}: PropsType) { + const [click, setClick] = useState(false); + const filterData = ['등록순', '이름순', '인기순']; + const navigate = useNavigate(); + + function handleModal() { + setClick((prev) => !prev); + } + + function selectSort(sort: string) { + navigate( + `/home/search?keyword=${forSearch.keyword}&category=${forSearch.category}&map=${forSearch.map}&location=${forSearch.location}&sort=${sort}&hot=${forSearch.hot}`, + ); + } + + useEffect(() => { + setClick(false); + }, [forSearch.sort]); -function DateFilter() { return ( -

+
- 등록순 + {forSearch.sort} +
+ {filterData.map((data) => ( + { + selectSort(data); + }} + > + {data} + + ))} +
); } diff --git a/src/components/SearchFromHome/SearchList/LocationFilter/LocationFliterPage/LocationFliterPage.tsx b/src/components/SearchFromHome/SearchList/LocationFilter/LocationFliterPage/LocationFliterPage.tsx index db343e43..b75da888 100644 --- a/src/components/SearchFromHome/SearchList/LocationFilter/LocationFliterPage/LocationFliterPage.tsx +++ b/src/components/SearchFromHome/SearchList/LocationFilter/LocationFliterPage/LocationFliterPage.tsx @@ -32,13 +32,18 @@ function LocationFliterPage({forSearch, click, handleClick}: PropsType) { useEffect(() => { const locationData = forSearch.location.split(' '); - setArea(locationData[0]); - setSigungu(locationData[1]); + if (locationData[0] === '전국') { + setArea('전국'); + setSigungu('전체 지역'); + } else { + setArea(locationData[0]); + setSigungu(locationData[1]); + } }, [forSearch.location]); function submit() { navigate( - `/home/search?keyword=${forSearch.keyword}&category=${forSearch.category}&map=${forSearch.map}&location=${area} ${sigungu}&sort=${forSearch.sort}`, + `/home/search?keyword=${forSearch.keyword}&category=${forSearch.category}&map=${forSearch.map}&location=${area} ${sigungu}&sort=${forSearch.sort}&hot=${forSearch.hot}`, ); handleClick(); } @@ -48,7 +53,7 @@ function LocationFliterPage({forSearch, click, handleClick}: PropsType) { className={styles.container} style={{ position: window.innerWidth > 450 ? 'absolute' : 'fixed', - top: window.innerWidth > 450 ? '-88px' : 0, + top: 0, right: click ? '-100%' : 0, height: `${vh * 100}px`, }} diff --git a/src/components/SearchFromHome/SearchList/Map/Map.tsx b/src/components/SearchFromHome/SearchList/Map/Map.tsx index 10e974fd..e43b5669 100644 --- a/src/components/SearchFromHome/SearchList/Map/Map.tsx +++ b/src/components/SearchFromHome/SearchList/Map/Map.tsx @@ -45,7 +45,7 @@ function Map({data, categoryChange}: PropsType) { const markerImage = new window.kakao.maps.MarkerImage(image, imageSize, imageOption); const marker = new window.kakao.maps.Marker({ - position: new window.kakao.maps.LatLng(data.location.latitude, data.location.longtitude), + position: new window.kakao.maps.LatLng(data.location.latitude, data.location.longitude), image: markerImage, }); return marker; @@ -121,6 +121,7 @@ function Map({data, categoryChange}: PropsType) { level: 4, }; setMap(new window.kakao.maps.Map(container, options)); + console.log(data); }, [data]); // 맵 생성 시 현재 데이터 좌표들의 바운드를 만들어 중심점 생성 @@ -130,7 +131,7 @@ function Map({data, categoryChange}: PropsType) { setSmallPin(data); setBigPin(data); data.map((data) => { - bounds.extend(new window.kakao.maps.LatLng(data.location.latitude, data.location.longtitude)); + bounds.extend(new window.kakao.maps.LatLng(data.location.latitude, data.location.longitude)); }); map.setBounds(bounds); } diff --git a/src/components/SearchFromHome/SearchList/Map/MapItems/MapItem/MapItem.tsx b/src/components/SearchFromHome/SearchList/Map/MapItems/MapItem/MapItem.tsx index 20b0c8ed..293e84d6 100644 --- a/src/components/SearchFromHome/SearchList/Map/MapItems/MapItem/MapItem.tsx +++ b/src/components/SearchFromHome/SearchList/Map/MapItems/MapItem/MapItem.tsx @@ -1,36 +1,26 @@ -import { Link } from "react-router-dom"; +import {Link} from 'react-router-dom'; -import styles from "./MapItem.module.scss"; +import styles from './MapItem.module.scss'; -import areas from "@/utils/areas.json"; +import {translateCategoryToStr} from '@/hooks/Search/useSearch'; -import { SearchItemType } from "@/types/home"; +import areas from '@/utils/areas.json'; + +import {SearchItemType} from '@/types/home'; interface PropsType { data: SearchItemType; categoryChange: boolean; } -function MapItem({ data, categoryChange }: PropsType) { - const location = areas.filter( - (area) => area.areaCode === data.location.areaCode, - )[0].name; - const category = - data.category === "관광지" || - data.category === "문화시설" || - data.category === "레포츠" || - data.category === "쇼핑" - ? "관광" - : data.category; +function MapItem({data, categoryChange}: PropsType) { + const location = areas.filter((area) => area.areaCode === data.location.areaCode)[0].name; + const category = translateCategoryToStr(data.contentTypeId); return ( - {`${data.title}의 -

+ {`${data.title}의 +

{data.title} {category}·{location} diff --git a/src/components/SearchFromHome/SearchList/Map/MapItems/MapItems.tsx b/src/components/SearchFromHome/SearchList/Map/MapItems/MapItems.tsx index 60940f27..ef32a661 100644 --- a/src/components/SearchFromHome/SearchList/Map/MapItems/MapItems.tsx +++ b/src/components/SearchFromHome/SearchList/Map/MapItems/MapItems.tsx @@ -1,14 +1,14 @@ -import { useEffect, useState } from "react"; +import {useEffect, useState} from 'react'; -import styles from "./MapItems.module.scss"; +import styles from './MapItems.module.scss'; -import useComponentSize from "@/hooks/useComponetSize"; +import useComponentSize from '@/hooks/useComponetSize'; -import SlideButton from "@/components/SlideButton/SlideButton"; +import SlideButton from '@/components/SlideButton/SlideButton'; -import MapItem from "./MapItem/MapItem"; +import MapItem from './MapItem/MapItem'; -import { SearchItemType } from "@/types/home"; +import {SearchItemType} from '@/types/home'; interface PropsType { data: SearchItemType[]; @@ -32,14 +32,12 @@ function MapItems({ const [throttle, setThrottle] = useState(true); function setCurrentIndex() { - const criterion = document.querySelector("#map_slide_container"); - const elements = document.querySelectorAll("#map_slide"); + const criterion = document.querySelector('#map_slide_container'); + const elements = document.querySelectorAll('#map_slide'); const childrenArray = Array.from(elements[0].children); for (const item of childrenArray) { - const currentLeft = - criterion && - item.getBoundingClientRect().x - criterion.getBoundingClientRect().x; + const currentLeft = criterion && item.getBoundingClientRect().x - criterion.getBoundingClientRect().x; if (currentLeft) { if (0 < currentLeft && currentLeft < 150) { const index = childrenArray.indexOf(item); @@ -65,10 +63,11 @@ function MapItems({ useEffect(() => { if (size.width < 449) { - componentRef.current?.scrollTo({ left: 0, behavior: "smooth" }); + componentRef.current?.scrollTo({left: 0, behavior: 'smooth'}); } else { setSlideLocation(0); } + console.log(data); }, [data, size, componentRef]); useEffect(() => { @@ -96,7 +95,7 @@ function MapItems({ }, [throttle]); return ( -

+
{data && ( - {data && - data.map((data, i) => ( - - ))} + {data && data.map((data, i) => )}
); diff --git a/src/components/SearchFromHome/SearchList/SearchItem/SearchItem.module.scss b/src/components/SearchFromHome/SearchList/SearchItem/SearchItem.module.scss index a5e0b57d..99ed157b 100644 --- a/src/components/SearchFromHome/SearchList/SearchItem/SearchItem.module.scss +++ b/src/components/SearchFromHome/SearchList/SearchItem/SearchItem.module.scss @@ -1,4 +1,4 @@ -@use "@/sass" as *; +@use '@/sass' as *; .container { width: 100%; @@ -18,6 +18,8 @@ opacity: 1; transition: 0.3s all linear; + + background-color: $neutral200; } .text { diff --git a/src/components/SearchFromHome/SearchList/SearchItem/SearchItem.tsx b/src/components/SearchFromHome/SearchList/SearchItem/SearchItem.tsx index 21c82a0d..30508ddd 100644 --- a/src/components/SearchFromHome/SearchList/SearchItem/SearchItem.tsx +++ b/src/components/SearchFromHome/SearchList/SearchItem/SearchItem.tsx @@ -1,37 +1,35 @@ -import { Link } from "react-router-dom"; +import {Link} from 'react-router-dom'; -import styles from "./SearchItem.module.scss"; +import styles from './SearchItem.module.scss'; -import areas from "@/utils/areas.json"; +import {translateCategoryToStr} from '@/hooks/Search/useSearch'; -import { SearchItemType } from "@/types/home"; +import nullImg from '@/assets/homeIcons/search/nullImg.svg'; +import areas from '@/utils/areas.json'; +import titleCaseChange from '@/utils/titleCaseChange'; + +import {SearchItemType} from '@/types/home'; interface PropsType { data: SearchItemType; categoryChange: boolean; } -function SearchItem({ data, categoryChange }: PropsType) { - const location = areas.filter( - (area) => area.areaCode === data.location.areaCode, - )[0].name; - const category = - data.category === "관광지" || - data.category === "문화시설" || - data.category === "레포츠" || - data.category === "쇼핑" - ? "관광" - : data.category; +function SearchItem({data, categoryChange}: PropsType) { + const title = titleCaseChange(data.title); + const location = areas.filter((area) => area.areaCode === data.location.areaCode)[0].name; + const category = translateCategoryToStr(data.contentTypeId); + const imgSrc = data.thumbnail ? data.thumbnail : nullImg; return ( {`${data.title}의 -

- {data.title} +

+ {title} {category}·{location} diff --git a/src/components/SearchFromHome/SearchList/SearchList.module.scss b/src/components/SearchFromHome/SearchList/SearchList.module.scss index 5836bbf5..6688c567 100644 --- a/src/components/SearchFromHome/SearchList/SearchList.module.scss +++ b/src/components/SearchFromHome/SearchList/SearchList.module.scss @@ -1,8 +1,6 @@ -@use "@/sass" as *; +@use '@/sass' as *; .container { - position: relative; - width: 100%; display: flex; diff --git a/src/components/SearchFromHome/SearchList/SearchList.tsx b/src/components/SearchFromHome/SearchList/SearchList.tsx index b27d2703..8de7683e 100644 --- a/src/components/SearchFromHome/SearchList/SearchList.tsx +++ b/src/components/SearchFromHome/SearchList/SearchList.tsx @@ -1,9 +1,9 @@ import {useEffect, useState} from 'react'; -import {useNavigate, useSearchParams} from 'react-router-dom'; +import {useNavigate} from 'react-router-dom'; import styles from './SearchList.module.scss'; -import {getData} from '@/mocks/handlers/home'; +import {keywordSearch, search} from '@/hooks/Search/useSearch'; import DateFilter from './DateFilter/DateFilter'; import LocationFilter from './LocationFilter/LocationFilter'; @@ -16,23 +16,21 @@ import {ForSearchType, SearchItemType} from '@/types/home'; interface PropsType { forSearch: ForSearchType; - keywordClick: boolean; } -function SearchList({forSearch, keywordClick}: PropsType) { - const [data, setData] = useState(); - const [filterData, setFilterData] = useState(); +function SearchList({forSearch}: PropsType) { + const [data, setData] = useState(); + const [filterData, setFilterData] = useState(); const [categoryChange, setCategoryChange] = useState(false); const navigate = useNavigate(); - const [searchParams] = useSearchParams(); useEffect(() => { - if (!keywordClick) { - getData('api/home/search/search', setData); + if (forSearch.hot === 'true') { + keywordSearch(forSearch.keyword, forSearch.location, forSearch.sort, setData); } else { - getData('api/home/search/search', setData); + search(forSearch.keyword, forSearch.location, forSearch.sort, setData); } - }, [searchParams]); + }, [forSearch.keyword, forSearch.location, forSearch.sort, forSearch.hot]); useEffect(() => { if (data) { @@ -52,20 +50,20 @@ function SearchList({forSearch, keywordClick}: PropsType) { function onMap() { navigate( - `/home/search?keyword=${forSearch.keyword}&category=${forSearch.category}&map=true&location=${forSearch.location}&sort=${forSearch.sort}`, + `/home/search?keyword=${forSearch.keyword}&category=${forSearch.category}&map=true&location=${forSearch.location}&sort=${forSearch.sort}&hot=${forSearch.hot}`, ); } return (

- + {forSearch.hot === 'false' && } {forSearch.map === 'true' && filterData ? ( ) : ( <>
- +
    {filterData && diff --git a/src/components/SearchFromHome/SearchList/Tabs/Tab/Tab.tsx b/src/components/SearchFromHome/SearchList/Tabs/Tab/Tab.tsx index f0fdbbdf..5e0a150d 100644 --- a/src/components/SearchFromHome/SearchList/Tabs/Tab/Tab.tsx +++ b/src/components/SearchFromHome/SearchList/Tabs/Tab/Tab.tsx @@ -21,7 +21,7 @@ function Tab({forSearch, thisCategory, setCategoryChange}: PropsType) { setCategoryChange(false); }, 150); navigate( - `/home/search?keyword=${forSearch.keyword}&category=${key}&map=${forSearch.map}&location=${forSearch.location}&sort=${forSearch.sort}`, + `/home/search?keyword=${forSearch.keyword}&category=${key}&map=${forSearch.map}&location=${forSearch.location}&sort=${forSearch.sort}&hot=${forSearch.hot}`, ); } diff --git a/src/hooks/Search/useSearch.ts b/src/hooks/Search/useSearch.ts index 5a26a491..4f5dead0 100644 --- a/src/hooks/Search/useSearch.ts +++ b/src/hooks/Search/useSearch.ts @@ -1,5 +1,10 @@ -import {getSearchData} from '@/api/search'; +import axios from 'axios'; +import {Dispatch} from 'react'; + import areaData from '@/utils/areas.json'; +import categoryData from '@/utils/categories.json'; + +import {SearchItemType} from '@/types/home'; function translateLocation(location: string) { const searchLocation = location.split(' '); @@ -92,18 +97,58 @@ export function translateCategoryToStr(category: number) { return categoryCode; } -export function search(keyword: string, location: string, sort: string) { - const searchLocation = translateLocation(location); +export function translateCategoryCode(name: string) { + const categoryCode = categoryData.filter((data) => data.name === name)[0]; + return categoryCode.code; +} - const searchData = getSearchData( - 0, - searchLocation.areaCode, - searchLocation.sigunguCode, - 0, - keyword, - translateSort(sort), - 'A05020900', - ); +export async function search( + keyword: string, + location: string, + sort: string, + set: Dispatch>, +) { + try { + const searchLocation = translateLocation(location); + const fetchData = await axios.get('/api/places/search', { + params: { + page: 0, + size: 20, + areaCode: searchLocation.areaCode, + sigunguCode: searchLocation.sigunguCode, + keyword: keyword, + sort: translateSort(sort), + }, + }); + const data = fetchData.data; + set(data?.data.places); + } catch (error) { + console.log(error); + } +} - return searchData; +export async function keywordSearch( + keyword: string, + location: string, + sort: string, + set: Dispatch>, +) { + try { + const searchLocation = translateLocation(location); + const categoryCode = translateCategoryCode(keyword); + const fetchData = await axios.get('/api/places/search', { + params: { + page: 0, + size: 20, + areaCode: searchLocation.areaCode, + sigunguCode: searchLocation.sigunguCode, + sort: translateSort(sort), + categoryCode: categoryCode, + }, + }); + const data = fetchData.data; + set(data?.data.places); + } catch (error) { + console.log(error); + } } diff --git a/src/mocks/handlers/home.ts b/src/mocks/handlers/home.ts index 82d9f30d..c45a6397 100644 --- a/src/mocks/handlers/home.ts +++ b/src/mocks/handlers/home.ts @@ -50,433 +50,445 @@ const tripSpaceData = [ }, ]; // 홈 검색 -const searchKeywordData = [ - {name: '감자', code: ''}, - {name: '강릉 감자', code: ''}, - {name: '강릉 감자유원지', code: ''}, - {name: '부산', code: ''}, - {name: '울산 맛집', code: ''}, - {name: '해운대 카페', code: ''}, - {name: '광안리 횟집', code: ''}, - {name: '깡통시장 깡돼후', code: ''}, -]; -const hotPlaces = [ - { - title: '대전 성심당', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - areaCode: 3, - sigumguCode: 0, - category: '맛집', - id: 1, - contentTypeId: 0, - }, - { - title: '대전 성심당', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - areaCode: 3, - sigumguCode: 0, - category: '맛집', - id: 1, - contentTypeId: 0, - }, - { - title: '대전 성심당', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - areaCode: 3, - sigumguCode: 0, - category: '맛집', - id: 1, - contentTypeId: 0, - }, - { - title: '대전 성심당', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - areaCode: 3, - sigumguCode: 0, - category: '맛집', - id: 1, - contentTypeId: 0, - }, - { - title: '대전 성심당', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - areaCode: 3, - sigumguCode: 0, - category: '맛집', - id: 1, - contentTypeId: 0, - }, - { - title: '대전 성심당', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - areaCode: 3, - sigumguCode: 0, - category: '맛집', - id: 1, - contentTypeId: 0, - }, - { - title: '대전 성심당', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - areaCode: 3, - sigumguCode: 0, - category: '맛집', - id: 1, - contentTypeId: 0, - }, - { - title: '대전 성심당', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - areaCode: 3, - sigumguCode: 0, - category: '맛집', - id: 1, - contentTypeId: 0, - }, - { - title: '대전 성심당', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - areaCode: 3, - sigumguCode: 0, - category: '맛집', - id: 1, - contentTypeId: 0, - }, - { - title: '대전 성심당', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - areaCode: 3, - sigumguCode: 0, - category: '맛집', - id: 1, - contentTypeId: 0, - }, -]; -const searchItemData = [ - { - id: 0, - contentTypeId: 32, - title: '신라호텔', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - location: { - address: '서울', - addressDetail: '서울', - phone: '0', - areaCode: 1, - sigunguCode: 1, - zipCode: 1, - latitude: 37.5559034, - longtitude: 127.0052509, +const searchKeywordData = { + keywords: [ + {name: '감자', code: ''}, + {name: '강릉 감자', code: ''}, + {name: '강릉 감자유원지', code: ''}, + {name: '부산', code: ''}, + {name: '울산 맛집', code: ''}, + {name: '해운대 카페', code: ''}, + {name: '광안리 횟집', code: ''}, + {name: '깡통시장 깡돼후', code: ''}, + ], +}; + +const hotPlaces = { + data: { + data: { + places: [ + { + title: '대전 성심당', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + areaCode: 3, + sigumguCode: 0, + category: '맛집', + id: 1, + contentTypeId: 0, + }, + { + title: '대전 성심당', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + areaCode: 3, + sigumguCode: 0, + category: '맛집', + id: 1, + contentTypeId: 0, + }, + { + title: '대전 성심당', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + areaCode: 3, + sigumguCode: 0, + category: '맛집', + id: 1, + contentTypeId: 0, + }, + { + title: '대전 성심당', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + areaCode: 3, + sigumguCode: 0, + category: '맛집', + id: 1, + contentTypeId: 0, + }, + { + title: '대전 성심당', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + areaCode: 3, + sigumguCode: 0, + category: '맛집', + id: 1, + contentTypeId: 0, + }, + { + title: '대전 성심당', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + areaCode: 3, + sigumguCode: 0, + category: '맛집', + id: 1, + contentTypeId: 0, + }, + { + title: '대전 성심당', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + areaCode: 3, + sigumguCode: 0, + category: '맛집', + id: 1, + contentTypeId: 0, + }, + { + title: '대전 성심당', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + areaCode: 3, + sigumguCode: 0, + category: '맛집', + id: 1, + contentTypeId: 0, + }, + { + title: '대전 성심당', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + areaCode: 3, + sigumguCode: 0, + category: '맛집', + id: 1, + contentTypeId: 0, + }, + { + title: '대전 성심당', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + areaCode: 3, + sigumguCode: 0, + category: '맛집', + id: 1, + contentTypeId: 0, + }, + ], }, - category: '숙소', }, - { - id: 0, - contentTypeId: 32, - title: '조선호텔', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - location: { - address: '서울', - addressDetail: '서울', - phone: '0', - areaCode: 1, - sigunguCode: 1, - zipCode: 1, - latitude: 37.564378, - longtitude: 126.980058, +}; + +const searchItemData = { + places: [ + { + id: 0, + contentTypeId: 32, + title: '신라호텔', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + location: { + address: '서울', + addressDetail: '서울', + phone: '0', + areaCode: 1, + sigunguCode: 1, + zipCode: 1, + latitude: 37.5559034, + longtitude: 127.0052509, + }, + category: '숙소', }, - category: '숙소', - }, - { - id: 0, - contentTypeId: 32, - title: '그랜드하얏트', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - location: { - address: '서울', - addressDetail: '서울', - phone: '0', - areaCode: 1, - sigunguCode: 1, - zipCode: 1, - latitude: 37.539167, - longtitude: 126.9975, + { + id: 0, + contentTypeId: 32, + title: '조선호텔', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + location: { + address: '서울', + addressDetail: '서울', + phone: '0', + areaCode: 1, + sigunguCode: 1, + zipCode: 1, + latitude: 37.564378, + longtitude: 126.980058, + }, + category: '숙소', }, - category: '숙소', - }, - { - id: 0, - contentTypeId: 39, - title: '모던 아시안 누들 서비스', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - location: { - address: '서울', - addressDetail: '서울', - phone: '0', - areaCode: 1, - sigunguCode: 1, - zipCode: 1, - latitude: 37.521901, - longtitude: 127.0211758, + { + id: 0, + contentTypeId: 32, + title: '그랜드하얏트', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + location: { + address: '서울', + addressDetail: '서울', + phone: '0', + areaCode: 1, + sigunguCode: 1, + zipCode: 1, + latitude: 37.539167, + longtitude: 126.9975, + }, + category: '숙소', }, - category: '음식점', - }, - { - id: 0, - contentTypeId: 39, - title: '더 타코부스', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - location: { - address: '서울', - addressDetail: '서울', - phone: '0', - areaCode: 1, - sigunguCode: 1, - zipCode: 1, - latitude: 37.5251773, - longtitude: 127.0369327, + { + id: 0, + contentTypeId: 39, + title: '모던 아시안 누들 서비스', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + location: { + address: '서울', + addressDetail: '서울', + phone: '0', + areaCode: 1, + sigunguCode: 1, + zipCode: 1, + latitude: 37.521901, + longtitude: 127.0211758, + }, + category: '음식점', }, - category: '음식점', - }, - { - id: 0, - contentTypeId: 39, - title: '콴안다오', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - location: { - address: '서울', - addressDetail: '서울', - phone: '0', - areaCode: 1, - sigunguCode: 1, - zipCode: 1, - latitude: 37.5184448, - longtitude: 127.0214852, + { + id: 0, + contentTypeId: 39, + title: '더 타코부스', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + location: { + address: '서울', + addressDetail: '서울', + phone: '0', + areaCode: 1, + sigunguCode: 1, + zipCode: 1, + latitude: 37.5251773, + longtitude: 127.0369327, + }, + category: '음식점', }, - category: '음식점', - }, - { - id: 0, - contentTypeId: 39, - title: '네로우 패스', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - location: { - address: '서울', - addressDetail: '서울', - phone: '0', - areaCode: 1, - sigunguCode: 1, - zipCode: 1, - latitude: 37.5362994, - longtitude: 127.0006358, + { + id: 0, + contentTypeId: 39, + title: '콴안다오', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + location: { + address: '서울', + addressDetail: '서울', + phone: '0', + areaCode: 1, + sigunguCode: 1, + zipCode: 1, + latitude: 37.5184448, + longtitude: 127.0214852, + }, + category: '음식점', }, - category: '카페', - }, - { - id: 0, - contentTypeId: 12, - title: 'DDP', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - location: { - address: '서울', - addressDetail: '서울', - phone: '0', - areaCode: 1, - sigunguCode: 1, - zipCode: 1, - latitude: 37.5665256, - longtitude: 127.0092236, + { + id: 0, + contentTypeId: 39, + title: '네로우 패스', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + location: { + address: '서울', + addressDetail: '서울', + phone: '0', + areaCode: 1, + sigunguCode: 1, + zipCode: 1, + latitude: 37.5362994, + longtitude: 127.0006358, + }, + category: '카페', }, - category: '관광지', - }, - { - id: 0, - contentTypeId: 12, - title: '서울숲', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - location: { - address: '서울', - addressDetail: '서울', - phone: '0', - areaCode: 1, - sigunguCode: 1, - zipCode: 1, - latitude: 37.5443878, - longtitude: 127.0374424, + { + id: 0, + contentTypeId: 12, + title: 'DDP', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + location: { + address: '서울', + addressDetail: '서울', + phone: '0', + areaCode: 1, + sigunguCode: 1, + zipCode: 1, + latitude: 37.5665256, + longtitude: 127.0092236, + }, + category: '관광지', }, - category: '관광지', - }, - { - id: 0, - contentTypeId: 12, - title: '롯데월드', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - location: { - address: '서울', - addressDetail: '서울', - phone: '0', - areaCode: 1, - sigunguCode: 1, - zipCode: 1, - latitude: 37.5111158, - longtitude: 127.098167, + { + id: 0, + contentTypeId: 12, + title: '서울숲', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + location: { + address: '서울', + addressDetail: '서울', + phone: '0', + areaCode: 1, + sigunguCode: 1, + zipCode: 1, + latitude: 37.5443878, + longtitude: 127.0374424, + }, + category: '관광지', }, - category: '관광지', - }, - { - id: 0, - contentTypeId: 14, - title: '국립중앙박물관', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - location: { - address: '서울', - addressDetail: '서울', - phone: '0', - areaCode: 1, - sigunguCode: 1, - zipCode: 1, - latitude: 37.5238506, - longtitude: 126.9804702, + { + id: 0, + contentTypeId: 12, + title: '롯데월드', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + location: { + address: '서울', + addressDetail: '서울', + phone: '0', + areaCode: 1, + sigunguCode: 1, + zipCode: 1, + latitude: 37.5111158, + longtitude: 127.098167, + }, + category: '관광지', }, - category: '문화시설', - }, - { - id: 0, - contentTypeId: 15, - title: '디큐브아트센터', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - location: { - address: '서울', - addressDetail: '서울', - phone: '0', - areaCode: 1, - sigunguCode: 1, - zipCode: 1, - latitude: 37.5090068, - longtitude: 126.8896308, + { + id: 0, + contentTypeId: 14, + title: '국립중앙박물관', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + location: { + address: '서울', + addressDetail: '서울', + phone: '0', + areaCode: 1, + sigunguCode: 1, + zipCode: 1, + latitude: 37.5238506, + longtitude: 126.9804702, + }, + category: '문화시설', }, - category: '문화시설', - }, - { - id: 0, - contentTypeId: 14, - title: '인사아트프라자갤러리', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - location: { - address: '서울', - addressDetail: '서울', - phone: '0', - areaCode: 1, - sigunguCode: 1, - zipCode: 1, - latitude: 37.5738118, - longtitude: 126.9855797, + { + id: 0, + contentTypeId: 15, + title: '디큐브아트센터', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + location: { + address: '서울', + addressDetail: '서울', + phone: '0', + areaCode: 1, + sigunguCode: 1, + zipCode: 1, + latitude: 37.5090068, + longtitude: 126.8896308, + }, + category: '문화시설', }, - category: '문화시설', - }, - { - id: 0, - contentTypeId: 28, - title: '한강', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - location: { - address: '서울', - addressDetail: '서울', - phone: '0', - areaCode: 1, - sigunguCode: 1, - zipCode: 1, - latitude: 37.5284304, - longtitude: 126.9330781, + { + id: 0, + contentTypeId: 14, + title: '인사아트프라자갤러리', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + location: { + address: '서울', + addressDetail: '서울', + phone: '0', + areaCode: 1, + sigunguCode: 1, + zipCode: 1, + latitude: 37.5738118, + longtitude: 126.9855797, + }, + category: '문화시설', }, - category: '레포츠', - }, - { - id: 0, - contentTypeId: 28, - title: '석호정', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - location: { - address: '서울', - addressDetail: '서울', - phone: '0', - areaCode: 1, - sigunguCode: 1, - zipCode: 1, - latitude: 37.5551076, - longtitude: 127.0003094, + { + id: 0, + contentTypeId: 28, + title: '한강', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + location: { + address: '서울', + addressDetail: '서울', + phone: '0', + areaCode: 1, + sigunguCode: 1, + zipCode: 1, + latitude: 37.5284304, + longtitude: 126.9330781, + }, + category: '레포츠', }, - category: '레포츠', - }, - { - id: 0, - contentTypeId: 28, - title: '남산 케이블카', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - location: { - address: '서울', - addressDetail: '서울', - phone: '0', - areaCode: 1, - sigunguCode: 1, - zipCode: 1, - latitude: 37.5565908, - longtitude: 126.9839744, + { + id: 0, + contentTypeId: 28, + title: '석호정', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + location: { + address: '서울', + addressDetail: '서울', + phone: '0', + areaCode: 1, + sigunguCode: 1, + zipCode: 1, + latitude: 37.5551076, + longtitude: 127.0003094, + }, + category: '레포츠', }, - category: '레포츠', - }, - { - id: 0, - contentTypeId: 38, - title: '더 현대', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - location: { - address: '서울', - addressDetail: '서울', - phone: '0', - areaCode: 1, - sigunguCode: 1, - zipCode: 1, - latitude: 37.5258975, - longtitude: 126.9284261, + { + id: 0, + contentTypeId: 28, + title: '남산 케이블카', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + location: { + address: '서울', + addressDetail: '서울', + phone: '0', + areaCode: 1, + sigunguCode: 1, + zipCode: 1, + latitude: 37.5565908, + longtitude: 126.9839744, + }, + category: '레포츠', }, - category: '쇼핑', - }, - { - id: 0, - contentTypeId: 38, - title: '타임스퀘어', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - location: { - address: '서울', - addressDetail: '서울', - phone: '0', - areaCode: 1, - sigunguCode: 1, - zipCode: 1, - latitude: 37.5169933, - longtitude: 126.9035425, + { + id: 0, + contentTypeId: 38, + title: '더 현대', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + location: { + address: '서울', + addressDetail: '서울', + phone: '0', + areaCode: 1, + sigunguCode: 1, + zipCode: 1, + latitude: 37.5258975, + longtitude: 126.9284261, + }, + category: '쇼핑', }, - category: '쇼핑', - }, - { - id: 0, - contentTypeId: 38, - title: '스타필드', - thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', - location: { - address: '서울', - addressDetail: '서울', - phone: '0', - areaCode: 1, - sigunguCode: 1, - zipCode: 1, - latitude: 37.5113686, - longtitude: 127.0595931, + { + id: 0, + contentTypeId: 38, + title: '타임스퀘어', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + location: { + address: '서울', + addressDetail: '서울', + phone: '0', + areaCode: 1, + sigunguCode: 1, + zipCode: 1, + latitude: 37.5169933, + longtitude: 126.9035425, + }, + category: '쇼핑', }, - category: '쇼핑', - }, -]; + { + id: 0, + contentTypeId: 38, + title: '스타필드', + thumbnail: 'https://m.eejmall.com/web/product/big/201708/211_shop1_627935.jpg', + location: { + address: '서울', + addressDetail: '서울', + phone: '0', + areaCode: 1, + sigunguCode: 1, + zipCode: 1, + latitude: 37.5113686, + longtitude: 127.0595931, + }, + category: '쇼핑', + }, + ], +}; export const home = [ // 홈 @@ -501,7 +513,7 @@ export const home = [ status: 200, }); }), - http.get('api/home/search/search', () => { + http.get('api/places/search', () => { return HttpResponse.json(searchItemData, { status: 200, }); diff --git a/src/pages/Home/Home.tsx b/src/pages/Home/Home.tsx index 37e3db33..bf9d0bb6 100644 --- a/src/pages/Home/Home.tsx +++ b/src/pages/Home/Home.tsx @@ -26,6 +26,7 @@ function Home() { }, []); useLockBodyScroll(modal); + useLockBodyScroll(!onboarding); useEffect(() => { if (cookies.inviteCode) { diff --git a/src/pages/SearchFromHome/SearchFromHome.tsx b/src/pages/SearchFromHome/SearchFromHome.tsx index 3c93a13b..2f71c49d 100644 --- a/src/pages/SearchFromHome/SearchFromHome.tsx +++ b/src/pages/SearchFromHome/SearchFromHome.tsx @@ -3,8 +3,6 @@ import {useSearchParams} from 'react-router-dom'; import styles from './SearchFromHome.module.scss'; -import {search} from '@/hooks/Search/useSearch'; - import MapHeader from '@/components/SearchFromHome/MapHeader/MapHeader'; import SearchBar from '@/components/SearchFromHome/SearchBar/SearchBar'; import SearchHome from '@/components/SearchFromHome/SearchHome/SearchHome'; @@ -17,9 +15,9 @@ function SearchFromHome() { map: 'false', location: '전국', sort: '등록순', + hot: 'false', }); const [searchParams] = useSearchParams(); - const [kewordClick, setKeywordClick] = useState(false); const vh = window.innerHeight; useEffect(() => { @@ -29,17 +27,25 @@ function SearchFromHome() { map: searchParams.get('map'), location: searchParams.get('location'), sort: searchParams.get('sort'), + hot: searchParams.get('hot'), }; - if (querystring.keyword && querystring.category && querystring.location && querystring.map && querystring.sort) { + if ( + querystring.keyword && + querystring.category && + querystring.location && + querystring.map && + querystring.sort && + querystring.hot + ) { setForSearch({ keyword: querystring.keyword, category: parseInt(querystring.category), map: querystring.map, location: querystring.location, sort: querystring.sort, + hot: querystring.hot, }); - console.log(search(querystring.keyword, querystring.location, querystring.sort)); } }, [searchParams]); @@ -48,7 +54,7 @@ function SearchFromHome() { className={styles.container} style={{ height: `${vh}px`, - gap: forSearch.map === 'true' ? '0' : '24px', + gap: forSearch.map === 'true' || forSearch.hot === 'true' ? '0' : '24px', paddingTop: forSearch.map === 'true' ? '0' : '16px', }} > @@ -57,11 +63,7 @@ function SearchFromHome() { ) : ( )} - {forSearch.keyword === '' ? ( - - ) : ( - - )} + {forSearch.keyword === '' ? : }
); } diff --git a/src/types/home.ts b/src/types/home.ts index 5fae2043..435f53a1 100644 --- a/src/types/home.ts +++ b/src/types/home.ts @@ -50,6 +50,29 @@ export interface SlideButtonPropsType extends LeftButtonPropsType { } // 홈 검색 타입 +export interface SearchDataType { + status: number; + message: string; + data: T; +} + +export interface Keywords { + keywords: SearchKeywordType[]; +} + +export interface Search { + places: SearchItemType[]; +} + +export interface Popular { + places: SearchHotItemType[]; +} + +export interface SearchKeywordType { + name: string; + code: string; +} + export interface SearchItemLocationType { address: string; addressDetail: string; @@ -58,17 +81,17 @@ export interface SearchItemLocationType { sigunguCode: number; zipCode: number; latitude: number; - longtitude: number; + longitude: number; } export interface SearchHotItemType { + id: number; + contentTypeId: number; title: string; thumbnail: string; areaCode: number; sigunguCode: number; category: string; - id: number; - contentTypeId: number; } export interface SearchItemType { @@ -86,4 +109,5 @@ export interface ForSearchType { map: string; location: string; sort: string; + hot: string; } diff --git a/src/utils/titleCaseChange.ts b/src/utils/titleCaseChange.ts new file mode 100644 index 00000000..25d48e56 --- /dev/null +++ b/src/utils/titleCaseChange.ts @@ -0,0 +1,6 @@ +export default function titleCaseChange(title: string) { + const regex = /^([^[]+)/; + const titleMatch = title.match(regex); + const titleData = titleMatch && titleMatch.length > 1 ? titleMatch[1].trim() : title; + return titleData; +}