+ if (address && map) {
+ naver.maps.Service.geocode(
+ {
+ query: address,
+ },
+ function (status, response) {
+ if (status !== naver.maps.Service.Status.OK) {
+ return alert("주소를 찾을 수 없습니다.")
+ }
+
+ const result = response.v2.addresses[0]
+ const coords = new naver.maps.LatLng(result?.y, result?.x)
+
+ setCenterCoords(coords)
+
+ // 지도 중심 이동
+ map.setCenter(coords)
+
+ // 지도 확대
+ map.setZoom(15)
+
+ // 마커 생성 (선택적)
+ new naver.maps.Marker({
+ position: coords,
+ map: map,
+ icon: {
+ content: `
`,
- },
- })
+ },
+ })
+ }
+ )
}
- )
- }
- }, [address, map])
-
- // 지도 초기화 함수
- function initMap() {
- // 지도를 생성할 때 필요한 옵션 설정
- const mapOptions = {
- center: new naver.maps.LatLng(37.3595704, 127.105399), // 지도의 초기 중심 좌표
- zoom: 10, // 지도의 초기 확대 레벨
+ }, [address, map])
+
+ // 지도 초기화 함수
+ function initMap() {
+ // 지도를 생성할 때 필요한 옵션 설정
+ const mapOptions = {
+ center: new naver.maps.LatLng(37.3595704, 127.105399), // 지도의 초기 중심 좌표
+ zoom: 10, // 지도의 초기 확대 레벨
+ }
+
+ // 지도 생성
+ const createdMap = new naver.maps.Map(mapRef.current, mapOptions)
+
+ // 지도 상태 업데이트
+ setMap(createdMap)
}
- // 지도 생성
- const createdMap = new naver.maps.Map(mapRef.current, mapOptions)
-
- // 지도 상태 업데이트
- setMap(createdMap)
- }
-
- useEffect(() => {
- if (category === "tourspot") {
- clearMarkers()
- setShowTouristSpots(true)
- } else if (map && centerCoords && category === "food") {
- setShowTouristSpots(false)
- clearMarkers()
- axios
- .get(
- `http://localhost:8080/api/v1/locations/${category}?latitude=${centerCoords.lat()}&longitude=${centerCoords.lng()}&distance=${distance}`
- )
- .then((r) => {
- setNearAmenities(r.data)
- setPage(1)
- map.setCenter(centerCoords)
+ useEffect(() => {
+ if (category === "tourspot") {
+ clearMarkers()
+ setShowTouristSpots(true)
+ } else if (map && centerCoords && category === "food") {
+ setShowTouristSpots(false)
+ clearMarkers()
+ axios
+ .get(
+ `http://localhost:8080/api/v1/locations/${category}?latitude=${centerCoords.lat()}&longitude=${centerCoords.lng()}&distance=${distance}`
+ )
+ .then((r) => {
+ let newData = r.data.map((v) => {
+ return {
+ id: v.id,
+ name: v.name,
+ coord: {...v.coord},
+ dist: calculateDistance(v.coord.y, v.coord.x, centerCoords?.lat(), centerCoords?.lng()),
+ }
+ })
+ setNearAmenities(newData)
+ setPage(1)
+ map.setCenter(centerCoords)
+ })
+ }
+ }, [centerCoords, category, distance])
+
+ const clearMarkers = () => {
+ markers.forEach((v) => {
+ v.setMap(null)
})
+ setMarkers([])
}
- }, [centerCoords, category, distance])
- const clearMarkers = () => {
- markers.forEach((v) => {
- v.setMap(null)
- })
- setMarkers([])
- }
-
- useEffect(() => {
- if (nearAmenities.length !== 0) {
- if (!showTouristSpots) {
- if (markers.length !== 0) {
- markers.forEach((v, index) => {
- v.setMap(null)
- })
- setMarkers([])
- }
- nearAmenities.forEach((v) => {
- let latLng = new naver.maps.LatLng(v.coord.y, v.coord.x)
-
- markers.push(
- new naver.maps.Marker({
- position: latLng,
- title: v.name,
- map: map,
- icon: {
- content: `
+ useEffect(() => {
+ if (nearAmenities.length !== 0) {
+ if (!showTouristSpots) {
+ if (markers.length !== 0) {
+ markers.forEach((v, index) => {
+ v.setMap(null)
+ })
+ setMarkers([])
+ }
+ nearAmenities.forEach((v) => {
+ let latLng = new naver.maps.LatLng(v.coord.y, v.coord.x)
+
+ markers.push(
+ new naver.maps.Marker({
+ position: latLng,
+ title: v.name,
+ map: map,
+ icon: {
+ content: `
`,
- },
- zIndex: 100,
- })
- )
- })
- }
- }
- }, [nearAmenities])
+ },
+ zIndex: 100,
+ })
+ )
+ })
+ }
+ }
+ }, [nearAmenities])
- const handleOverInfo = (id) => {
- console.log(id)
- const element = document.getElementById("m-" + id)
+ const handleOverInfo = (id) => {
+ const element = document.getElementById("m-" + id)
- if (element) {
- element.style.border = "2px solid #2563EB"
- element.style.display = "block"
+ if (element) {
+ element.style.border = "2px solid #2563EB"
+ element.style.display = "block"
+ }
}
- }
- const handleOutInfo = (id) => {
- const element = document.getElementById("m-" + id)
+ const handleOutInfo = (id) => {
+ const element = document.getElementById("m-" + id)
- if (element) {
- element.style.border = "2px solid #fff"
- element.style.display = "none"
- }
- }
-
- const clearHtmlTags = (html) => {
- const tempDiv = document.createElement("div")
- tempDiv.innerHTML = html
- return tempDiv.textContent || tempDiv.innerText || ""
- }
-
- const renderCell = (item, columnKey) => {
- if (centerCoords) {
- switch (columnKey) {
- case "dist":
- return (
-
- {calculateDistance(
- item.coord.y,
- item.coord.x,
- centerCoords.lat(),
- centerCoords.lng()
- )}
- m
-
- )
- case "name":
- return clearHtmlTags(item.name)
- }
+ if (element) {
+ element.style.border = "2px solid #fff"
+ element.style.display = "none"
+ }
}
- }
-
- useEffect(() => {
- if (showTouristSpots && touristSpots.length > 0 && map) {
- let newTouristSpots = []
-
- touristSpots.forEach((v, index) => {
- newTouristSpots.push({
- id: index,
- name: v.title,
- coord: { x: v.mapx / 10000000, y: v.mapy / 10000000 },
- })
- })
- setNearAmenities(newTouristSpots)
- // 관광지 정보가 여러 개일 때 지도의 중심을 계산
- let bounds = new naver.maps.LatLngBounds()
-
- touristSpots.forEach((spot) => {
- const spots = new naver.maps.LatLng(
- spot.mapy / 10000000,
- spot.mapx / 10000000
- )
+ const clearHtmlTags = (html) => {
+ const tempDiv = document.createElement("div")
+ tempDiv.innerHTML = html
+ return tempDiv.textContent || tempDiv.innerText || ""
+ }
- bounds.extend(spots) // 관광지 위치를 포함하도록 경계 확장
+ const renderCell = (item, columnKey) => {
+ if (centerCoords) {
+ switch (columnKey) {
+ case "dist":
+ return (
+
+ {item?.dist}
+ m
+
+ )
+ case "name":
+ return clearHtmlTags(item.name)
+ }
+ }
+ }
- const marker = new naver.maps.Marker({
- position: spots,
- map: map,
- })
+ useEffect(() => {
+ if (showTouristSpots && touristSpots.length > 0 && map) {
+ let newTouristSpots = []
- const cleanTitle = document.createElement("div")
- cleanTitle.innerHTML = spot.title
- const textTitle = cleanTitle.textContent || cleanTitle.innerText
+ touristSpots.forEach((v, index) => {
+ newTouristSpots.push({
+ id: index,
+ name: v.title,
+ coord: {x: v.mapx / 10000000, y: v.mapy / 10000000},
+ })
+ })
- // 마커에 정보 창 추가
- const infoWindow = new naver.maps.InfoWindow({
- content: `
${textTitle}
`,
- disableAnchor: true, // 화살표 비활성화
- borderColor: "transparent",
- })
+ setNearAmenities(newTouristSpots)
+ // 관광지 정보가 여러 개일 때 지도의 중심을 계산
+ let bounds = new naver.maps.LatLngBounds()
+
+ touristSpots.forEach((spot) => {
+ const spots = new naver.maps.LatLng(
+ spot.mapy / 10000000,
+ spot.mapx / 10000000
+ )
+
+ bounds.extend(spots) // 관광지 위치를 포함하도록 경계 확장
+
+ const marker = new naver.maps.Marker({
+ position: spots,
+ map: map,
+ })
+
+ const cleanTitle = document.createElement("div")
+ cleanTitle.innerHTML = spot.title
+ const textTitle = cleanTitle.textContent || cleanTitle.innerText
+
+ // 마커에 정보 창 추가
+ const infoWindow = new naver.maps.InfoWindow({
+ content: `
${textTitle}
`,
+ disableAnchor: true, // 화살표 비활성화
+ borderColor: "transparent",
+ })
+
+ naver.maps.Event.addListener(marker, "mouseover", function () {
+ infoWindow.open(map, marker)
+ })
+
+ // 마커를 클릭하는 이벤트 핸들러
+ naver.maps.Event.addListener(marker, "click", function () {
+ const query = encodeURIComponent(textTitle) // 마커의 타이틀을 인코딩
+ const searchUrl = `https://search.naver.com/search.naver?query=${query}`
+
+ // 생성된 검색 URL로 리다이렉트
+ window.open(searchUrl, "_blank")
+ })
+
+ naver.maps.Event.addListener(marker, "mouseout", function () {
+ infoWindow.close()
+ })
+ console.log("Marker added:", marker)
+
+ markers.push(marker)
+ })
+ map.fitBounds(bounds)
+ }
+ }, [showTouristSpots, touristSpots, map])
- naver.maps.Event.addListener(marker, "mouseover", function () {
- infoWindow.open(map, marker)
- })
+ let list = useAsyncList({
+ async load({signal}) {
+ return {items: nearAmenities}
+ },
+ async sort({items, sortDescriptor}) {
+ return {
+ items: items.sort((a, b) => {
+ let first = a[sortDescriptor.column];
+ let second = b[sortDescriptor.column];
+ let cmp = (parseInt(first) || first) < (parseInt(second) || second) ? -1 : 1;
+
+ if (sortDescriptor.direction === "descending") {
+ cmp *= -1;
+ }
+
+ return cmp;
+ })
+ }
+ },
+ })
- // 마커를 클릭하는 이벤트 핸들러
- naver.maps.Event.addListener(marker, "click", function () {
- const query = encodeURIComponent(textTitle) // 마커의 타이틀을 인코딩
- const searchUrl = `https://search.naver.com/search.naver?query=${query}`
+ useEffect(() => {
+ list.reload();
+ }, [nearAmenities])
- // 생성된 검색 URL로 리다이렉트
- window.open(searchUrl, "_blank")
- })
+ const items = React.useMemo(() => {
+ const start = (page - 1) * rowsPerPage
+ const end = start + rowsPerPage
- naver.maps.Event.addListener(marker, "mouseout", function () {
- infoWindow.close()
- })
- console.log("Marker added:", marker)
+ return list.items?.slice(start, end)
+ }, [page, list.items])
- markers.push(marker)
- })
- map.fitBounds(bounds)
- }
- }, [showTouristSpots, touristSpots, map])
-
- return (
-
- {showTouristSpots && (
-
- )}
-
- 100M
- 300M
- 500M
-
-
-
- {
- setCategory(v)
- }}
- defaultValue={"food"}
- >
- 음식점
- 여행지
-
-
-
-
- 근처 {showTouristSpots ? "여행지" : distance + "M"} 결과{" "}
- {nearAmenities.length}개
-
-
- setPage(page)}
- classNames={{
- wrapper: ["flex w-full"],
- item: ["relative min-w-0"],
- }}
+ return (
+
+ {showTouristSpots && (
+
-
- }
- >
-
- NAME
- DISTANCE
-
-
- {(item) => (
- handleOverInfo(item.id)}
- onMouseOut={() => handleOutInfo(item.id)}
- >
- {(columnKey) => (
- {renderCell(item, columnKey)}
- )}
-
- )}
-
-
+ )}
+
+ 100M
+ 300M
+ 500M
+
+
+
+ {
+ setCategory(v)
+ }}
+ defaultValue={"food"}
+ >
+ 음식점
+ 여행지
+
+
+
+
+ 근처 {showTouristSpots ? "여행지" : distance + "M"} 결과{" "}
+ {nearAmenities.length}개
+
+
+ setPage(page)}
+ classNames={{
+ wrapper: ["flex w-full"],
+ item: ["relative min-w-0"],
+ }}
+ />
+
+ }
+ sortDescriptor={list.sortDescriptor}
+ onSortChange={list.sort}
+ >
+
+ NAME
+ DISTANCE
+
+
+ {(item) => (
+ handleOverInfo(item.id)}
+ onMouseOut={() => handleOutInfo(item.id)}
+ >
+ {(columnKey) => (
+ {renderCell(item, columnKey)}
+ )}
+
+ )}
+
+
+
+
-
-
- )
-}
+ )
+}
\ No newline at end of file
diff --git a/src/components/touristSpot/TouristSpotSearch.js b/src/components/touristSpot/TouristSpotSearch.js
index 170ea76..57249ea 100644
--- a/src/components/touristSpot/TouristSpotSearch.js
+++ b/src/components/touristSpot/TouristSpotSearch.js
@@ -1,41 +1,41 @@
-import React, { useState, useEffect } from "react"
+import {useEffect} from "react"
import axios from "@/config/axios-config"
-function TouristSpotSearch({ hotelAddress, onSearchResult }) {
- useEffect(() => {
- const searchTouristSpot = async (address) => {
- try {
- const apiUrl = `${process.env.NEXT_PUBLIC_BASE_URL}/v1/search/local.json?query=${address}`
- const response = await axios.get(apiUrl)
+function TouristSpotSearch({hotelAddress, onSearchResult}) {
+ useEffect(() => {
+ const searchTouristSpot = async (address) => {
+ try {
+ const apiUrl = `${process.env.NEXT_PUBLIC_BASE_URL}/v1/search/local.json?query=${address}`
+ const response = await axios.get(apiUrl)
- // 에러 확인
- if (response.data.error) {
- console.error("API Error:", response.data.error)
- return
- }
+ // 에러 확인
+ if (response.data.error) {
+ console.error("API Error:", response.data.error)
+ return
+ }
- // 정상적인 응답 확인
- const data = response.data
- console.log("API Response:", data)
+ // 정상적인 응답 확인
+ const data = response.data
+ console.log("API Response:", data)
- // data.items가 존재하고 배열인지 확인 후 사용
- if (data && Array.isArray(data)) {
- // 관광지 데이터를 전달하여 상태 업데이트
- onSearchResult(data)
- } else {
- console.error("Invalid response format")
+ // data.items가 존재하고 배열인지 확인 후 사용
+ if (data && Array.isArray(data)) {
+ // 관광지 데이터를 전달하여 상태 업데이트
+ onSearchResult(data)
+ } else {
+ console.error("Invalid response format")
+ }
+ } catch (error) {
+ console.error("API Request Error:", error)
+ }
}
- } catch (error) {
- console.error("API Request Error:", error)
- }
- }
- if (hotelAddress) {
- searchTouristSpot(hotelAddress)
- }
- }, [hotelAddress, onSearchResult])
+ if (hotelAddress) {
+ searchTouristSpot(hotelAddress)
+ }
+ }, [hotelAddress, onSearchResult])
- return null // 렌더링하지 않음
+ return null // 렌더링하지 않음
}
-export default TouristSpotSearch
+export default TouristSpotSearch
\ No newline at end of file