diff --git a/frontend/src/components/SearchMapByKeyword.js b/frontend/src/components/SearchMapByKeyword.js index 59d21e41e8c99cade1799f45838621c75461b10e..6a8a07c501c6896b1e781313b0144389ec192411 100644 --- a/frontend/src/components/SearchMapByKeyword.js +++ b/frontend/src/components/SearchMapByKeyword.js @@ -1,96 +1,134 @@ import { Map, MapMarker } from "react-kakao-maps-sdk"; import React, { useRef, useState, useEffect, useContext } from 'react'; -const {kakao} = window; +const { kakao } = window; -function SearchMapByKeyword({loc, setLoc}){ - // 아주대학교를 기본 위치로 설정 - const [info, setInfo] = useState() - const [markers, setMarkers] = useState([]) - const [map, setMap] = useState() - const [searchKeyword, setSearchKeyword] = useState(); //주소 입력 +function SearchMapByKeyword({ loc, setLoc }) { + // 아주대학교를 기본 위치로 설정 + const [info, setInfo] = useState() + const [markers, setMarkers] = useState([]) + const [pagination, setPagination] = useState() + const [map, setMap] = useState() + const [searchKeyword, setSearchKeyword] = useState(); //주소 입력 - const defaultCenter = { lat: 37.28238488648025, lng: 127.04350967609274 } - const ps = new kakao.maps.services.Places() + const defaultCenter = { lat: 37.28238488648025, lng: 127.04350967609274 } + const ps = new kakao.maps.services.Places() - const handleInput = (e) => { - setSearchKeyword(e.target.value); - } + const handleInput = (e) => { + setSearchKeyword(e.target.value); + } - const handleSearch = () => { - ps.keywordSearch(searchKeyword, (data, status, _pagination) => { - if (status === kakao.maps.services.Status.OK) { - // 검색된 장소 위치를 기준으로 지도 범위를 재설정하기위해 - // LatLngBounds 객체에 좌표를 추가합니다 - const bounds = new kakao.maps.LatLngBounds() - let markers = [] - - for (var i = 0; i < data.length; i++) { - // @ts-ignore - markers.push({ - position: { - lat: data[i].y, - lng: data[i].x, - }, - content: data[i].place_name, - }) - // @ts-ignore - bounds.extend(new kakao.maps.LatLng(data[i].y, data[i].x)) - } + const handleSearch = () => { + ps.keywordSearch(searchKeyword, (data, status, _pagination) => { + if (status === kakao.maps.services.Status.OK) { + // 검색된 장소 위치를 기준으로 지도 범위를 재설정하기위해 + // LatLngBounds 객체에 좌표를 추가합니다 + const bounds = new kakao.maps.LatLngBounds() + let markers = [] - setMarkers(markers) - - // 검색된 장소 위치를 기준으로 지도 범위를 재설정합니다 - //map.setBounds(bounds) + setPagination(_pagination); + + for (var i = 0; i < data.length; i++) { + // @ts-ignore + markers.push({ + position: { + lat: data[i].y, + lng: data[i].x, + }, + content: data[i].place_name, + }) + // @ts-ignore + bounds.extend(new kakao.maps.LatLng(data[i].y, data[i].x)) } - }) + + setMarkers(markers) + + // 검색된 장소 위치를 기준으로 지도 범위를 재설정합니다 + map.setBounds(bounds) + } + }, { category_group_code: 'FD6' }) + } + + const displayPagination = (pagination) => { + const links = []; + for(let i = 1; i <= pagination.last; i++) { + links.push(<a href="#" onClick={() => pagination.gotoPage(i)}>{i}</a>); } - return ( - <div className="UserInput"> - <input onChange={handleInput}/> - <button onClick={()=>handleSearch()}>검색</button><br></br> - <input readOnly={true} type="text" placeholder="장소 키워드" value={loc.keyword}/> - <input readOnly={true} type="text" placeholder="위도" value={loc.center.lat}/> - <input readOnly={true} type="text" placeholder="경도" value={loc.center.lng}/> - <Map // 지도를 표시할 Container - center={markers[0] && markers[0].position || defaultCenter} - style={{ - // 지도의 크기 - width: "450px", - height: "450px" - }} - level={3}> - {markers.map((marker) => ( - <MapMarker - key={`marker-${marker.content}-${marker.position.lat},${marker.position.lng}`} - position={marker.position} + return links; + } - clickable={true} // 마커를 클릭했을 때 지도의 클릭 이벤트가 발생하지 않도록 설정합니다 - // 마커에 마우스오버 이벤트를 등록합니다 - onMouseOver={ - // 마커에 마우스오버 이벤트가 발생하면 인포윈도우를 마커위에 표시합니다 - () => setInfo(marker) - } - // 마커에 마우스아웃 이벤트를 등록합니다 - onMouseOut={ - // 마커에 마우스아웃 이벤트가 발생하면 인포윈도우를 제거합니다 - () => setInfo(null) - } - onClick={() => { - setLoc({ - keyword: marker.content, - center: { lat: marker.position.lat, lng: marker.position.lng } - }) - }}> - {info &&info.content === marker.content && ( - <div style={{color:"#000"}}>{marker.content}</div> - )} - </MapMarker> - ))} - </Map> + return ( + <div className="UserInput"> + <input onChange={handleInput} /> + <button onClick={() => handleSearch()}>검색</button><br></br> + <input readOnly={true} type="text" placeholder="장소 키워드" value={loc.keyword} /> + <input readOnly={true} type="text" placeholder="위도" value={loc.center.lat} /> + <input readOnly={true} type="text" placeholder="경도" value={loc.center.lng} /> + <div style={{display: 'flex'}}> + <Map // 지도를 표시할 Container + center={info && info.position || defaultCenter} + style={{ + // 지도의 크기 + width: "450px", + height: "450px" + }} + onCreate={setMap} + isPanto={true} + level={3}> + {markers.map((marker) => ( + <MapMarker + key={`marker-${marker.content}-${marker.position.lat},${marker.position.lng}`} + position={marker.position} + clickable={true} // 마커를 클릭했을 때 지도의 클릭 이벤트가 발생하지 않도록 설정합니다 + // 마커에 마우스오버 이벤트를 등록합니다 + onMouseOver={ + // 마커에 마우스오버 이벤트가 발생하면 인포윈도우를 마커위에 표시합니다 + () => setInfo(marker) + } + // 마커에 마우스아웃 이벤트를 등록합니다 + onMouseOut={ + // 마커에 마우스아웃 이벤트가 발생하면 인포윈도우를 제거합니다 + () => setInfo({position: marker.position}) + } + onClick={() => { + setLoc({ + keyword: marker.content, + center: { lat: marker.position.lat, lng: marker.position.lng } + }); + }}> + {info && info.content === marker.content && ( + <div style={{ width:"100%", color: "#000" }}> + {marker.content} + </div> + )} + </MapMarker> + ))} + </Map> + <div> + <ul> + {markers.map((marker) => ( + <li key={`marker-${marker.content}-${marker.position.lat},${marker.position.lng}`} + onMouseOver={() => {setInfo(marker)}} + onMouseOut={() => {setInfo({position: marker.position})}}> + <a href="#" style={{textDecoration:"none", color:"black"}} onClick={() => { + setLoc({ + keyword: marker.content, + center: { lat: marker.position.lat, lng: marker.position.lng } + }) + }}>{marker.content}</a> + </li> + ))} + </ul> + <div style={{display:"flex", justifyContent:"center"}}> + { pagination && + displayPagination(pagination) + } + </div> </div> - ) + </div> + </div> + ) } export default SearchMapByKeyword \ No newline at end of file