diff --git a/public/assets/marker.png b/public/assets/marker.png new file mode 100644 index 00000000..d34034fe Binary files /dev/null and b/public/assets/marker.png differ diff --git a/src/app/map/page.tsx b/src/app/map/page.tsx index 9509ee89..866e1245 100644 --- a/src/app/map/page.tsx +++ b/src/app/map/page.tsx @@ -1,19 +1,39 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ + +'use client'; + +import { useState } from 'react'; + import classNames from 'classnames/bind'; +import Markers from '@/components/map/markers/Markers'; +import KakaoMap from '@components/map/kakao-map/KakaoMap'; +import useMarkers from '@remote/queries/map/useMarkers'; import BottomNav from '@shared/bottom-nav/BottomNav'; -import KakaoMap from '@shared/map/KakaoMap'; import SearchBar from '@shared/search-bar/SearchBar'; import styles from './page.module.scss'; const cx = classNames.bind(styles); function MapPage() { + // eslint-disable-next-line @typescript-eslint/naming-convention + const { data: carWashMarkers } = useMarkers({ + minX: 36.12, + maxX: 36.88, + minY: 127.1, + maxY: 127.8, + level: 2, + }); + const [map, setMap] = useState(null); + return (
- + +
); diff --git a/src/components/shared/map/CurrentLocationButton.module.scss b/src/components/map/kakao-map/CurrentLocationButton.module.scss similarity index 96% rename from src/components/shared/map/CurrentLocationButton.module.scss rename to src/components/map/kakao-map/CurrentLocationButton.module.scss index acc97bef..909505f0 100644 --- a/src/components/shared/map/CurrentLocationButton.module.scss +++ b/src/components/map/kakao-map/CurrentLocationButton.module.scss @@ -1,6 +1,7 @@ .button { position: absolute; z-index: var(--header-zindex); + right: 7%; bottom: 13%; box-sizing: border-box; margin-left: 24px; diff --git a/src/components/shared/map/CurrentLocationButton.tsx b/src/components/map/kakao-map/CurrentLocationButton.tsx similarity index 100% rename from src/components/shared/map/CurrentLocationButton.tsx rename to src/components/map/kakao-map/CurrentLocationButton.tsx diff --git a/src/components/shared/map/KakaoMap.tsx b/src/components/map/kakao-map/KakaoMap.tsx similarity index 92% rename from src/components/shared/map/KakaoMap.tsx rename to src/components/map/kakao-map/KakaoMap.tsx index 457b01a7..398816f1 100644 --- a/src/components/shared/map/KakaoMap.tsx +++ b/src/components/map/kakao-map/KakaoMap.tsx @@ -7,7 +7,7 @@ 'use client'; -import { useState } from 'react'; +import { SetStateAction, useState } from 'react'; import Script from 'next/script'; @@ -25,10 +25,12 @@ interface ILocation { lng: number; } -function KakaoMap() { - // eslint-disable-next-line @typescript-eslint/naming-convention - const [map, setMap] = useState(null); +interface IKakaoProps { + map: any + setMap: React.Dispatch> +} +function KakaoMap({ map, setMap }: IKakaoProps) { const loadKakaoMap = () => { window.kakao.maps.load(() => { const mapContainer = document.getElementById('map'); diff --git a/src/components/map/markers/Markers.tsx b/src/components/map/markers/Markers.tsx new file mode 100644 index 00000000..e40b2e66 --- /dev/null +++ b/src/components/map/markers/Markers.tsx @@ -0,0 +1,67 @@ +/* eslint-disable array-callback-return */ +/* eslint-disable max-len */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +/* eslint-disable @typescript-eslint/no-unsafe-call */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +import { useCallback, useEffect } from 'react'; + +import { MarkersType } from '@remote/api/types/map'; + +interface MarkerProps { + map: any + carwashs: MarkersType +} + +declare global { + interface Window { + kakao: any + } +} + +function Markers({ map, carwashs }: MarkerProps) { + const loadKakoMarkers = useCallback(() => { + if (map) { + // 식당 데이터 마커 띄우기 + carwashs?.value.map((carwash) => { + const imageSrc = '/assets/marker.png'; + const imageSize = new window.kakao.maps.Size(40, 40); // 마커이미지의 크기입니다 + const imageOption = { offset: new window.kakao.maps.Point(27, 69) }; // 마커이미지의 옵션입니다. 마커의 좌표와 일치시킬 이미지 안에서의 좌표를 설정합니다. + + // 마커의 이미지정보를 가지고 있는 마커이미지를 생성합니다 + const markerImage = new window.kakao.maps.MarkerImage( + imageSrc, + imageSize, + imageOption, + ); + + // 마커가 표시될 위치입니다 + const markerPosition = new window.kakao.maps.LatLng( + carwash.latitude, + carwash.longitude, + ); + + // 마커를 생성합니다 + const marker = new window.kakao.maps.Marker({ + position: markerPosition, + image: markerImage, // 마커이미지 설정 + }); + + // 마커가 지도 위에 표시되도록 설정합니다 + marker.setMap(map); + }); + } + }, [map, carwashs]); + + useEffect(() => { + loadKakoMarkers(); + }, [loadKakoMarkers, map]); + + return ( + // eslint-disable-next-line react/jsx-no-useless-fragment + <> + ); +} + +export default Markers; diff --git a/src/remote/api/requests/map/map.get.api.ts b/src/remote/api/requests/map/map.get.api.ts new file mode 100644 index 00000000..7fac0e39 --- /dev/null +++ b/src/remote/api/requests/map/map.get.api.ts @@ -0,0 +1,12 @@ +import { IMarkersParameter, MarkersType } from '../../types/map'; +import { getRequest } from '../requests.api'; + +// 세차장 위치 마커 + +export const getMarkers = async ({ + minX, maxX, minY, maxY, level, +}: IMarkersParameter) => { + const response = await getRequest(`/washzones?minX=${minX}&maxX=${maxX}&minY=${minY}&maxY=${maxY}&&level=${level}`); + + return response; +}; diff --git a/src/remote/api/types/map.ts b/src/remote/api/types/map.ts new file mode 100644 index 00000000..58e07b6d --- /dev/null +++ b/src/remote/api/types/map.ts @@ -0,0 +1,20 @@ +import { ICommon } from './common'; + +export interface IMarkersParameter { + minX: number + maxX: number + minY: number + maxY: number + level: number +} + +export interface IMarkers { + name: string + address: string + latitude: number + longitude: number + type: '실내' | '개러지' | null + remarks: null +} + +export type MarkersType = ICommon; diff --git a/src/remote/queries/map/useMarkers.tsx b/src/remote/queries/map/useMarkers.tsx new file mode 100644 index 00000000..bc87e63c --- /dev/null +++ b/src/remote/queries/map/useMarkers.tsx @@ -0,0 +1,19 @@ +import { useQuery } from '@tanstack/react-query'; + +import { getMarkers } from '@/remote/api/requests/map/map.get.api'; +import { IMarkersParameter, MarkersType } from '@/remote/api/types/map'; + +function useMarkers({ + minX, maxX, minY, maxY, level, +}: IMarkersParameter) { + return useQuery({ + queryKey: ['MarkerType', minX, minY, maxX, maxY, level], + queryFn: () => { + return getMarkers({ + minX, maxX, minY, maxY, level, + }); + }, + }); +} + +export default useMarkers;