diff --git a/package-lock.json b/package-lock.json index ac0e3b4..8bad7f2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,9 +26,11 @@ "react-query": "^3.39.3", "react-router-dom": "^6.24.0", "sass": "^1.77.6", + "tsid-ts": "^0.0.9", "typescript": "^4.9.5", "typescript-cookie": "^1.0.6", "web-vitals": "^2.1.4", + "yorkie-js-sdk": "^0.4.28", "zustand": "^4.5.4" }, "devDependencies": { @@ -2210,6 +2212,28 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@bufbuild/protobuf": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-1.10.0.tgz", + "integrity": "sha512-QDdVFLoN93Zjg36NoQPZfsVH9tZew7wKDKyV5qRdj8ntT4wQCOradQjRaTdwMhWUYsgKsvCINKKm87FdEk96Ag==" + }, + "node_modules/@connectrpc/connect": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@connectrpc/connect/-/connect-1.4.0.tgz", + "integrity": "sha512-vZeOkKaAjyV4+RH3+rJZIfDFJAfr+7fyYr6sLDKbYX3uuTVszhFe9/YKf5DNqrDb5cKdKVlYkGn6DTDqMitAnA==", + "peerDependencies": { + "@bufbuild/protobuf": "^1.4.2" + } + }, + "node_modules/@connectrpc/connect-web": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@connectrpc/connect-web/-/connect-web-1.4.0.tgz", + "integrity": "sha512-13aO4psFbbm7rdOFGV0De2Za64DY/acMspgloDlcOKzLPPs0yZkhp1OOzAQeiAIr7BM/VOHIA3p8mF0inxCYTA==", + "peerDependencies": { + "@bufbuild/protobuf": "^1.4.2", + "@connectrpc/connect": "1.4.0" + } + }, "node_modules/@csstools/normalize.css": { "version": "12.1.1", "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.1.1.tgz", @@ -14074,6 +14098,11 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -19381,6 +19410,11 @@ "node": ">=4" } }, + "node_modules/tsid-ts": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/tsid-ts/-/tsid-ts-0.0.9.tgz", + "integrity": "sha512-UQtHUWLO65lUht9m3Iy9iO7fxy1197L3CWEWP19VMCUpMZ548LSuWaTaLIL7NKdiWRJ6z7HJeuAJoVJ29NllnA==" + }, "node_modules/tslib": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", @@ -21092,6 +21126,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/yorkie-js-sdk": { + "version": "0.4.28", + "resolved": "https://registry.npmjs.org/yorkie-js-sdk/-/yorkie-js-sdk-0.4.28.tgz", + "integrity": "sha512-laDG5LVXV1mW085F4BdagUgIgU4hd+QBD0kon8kAeVA086ZGwXRMlFSYhEZtY1bB+RTSDSe4i78vVGG2Kv6bcg==", + "dependencies": { + "@bufbuild/protobuf": "^1.6.0", + "@connectrpc/connect": "^1.4.0", + "@connectrpc/connect-web": "^1.4.0", + "long": "^5.2.0" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=7.1.0" + } + }, "node_modules/zustand": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.4.tgz", diff --git a/package.json b/package.json index 432cba2..eb84f2a 100644 --- a/package.json +++ b/package.json @@ -21,9 +21,11 @@ "react-query": "^3.39.3", "react-router-dom": "^6.24.0", "sass": "^1.77.6", + "tsid-ts": "^0.0.9", "typescript": "^4.9.5", "typescript-cookie": "^1.0.6", "web-vitals": "^2.1.4", + "yorkie-js-sdk": "^0.4.28", "zustand": "^4.5.4" }, "scripts": { diff --git a/src/apis/auth/useProfileEditMutation.ts b/src/apis/auth/useProfileEditMutation.ts new file mode 100644 index 0000000..a187738 --- /dev/null +++ b/src/apis/auth/useProfileEditMutation.ts @@ -0,0 +1,62 @@ +import { useMutation } from 'react-query'; +import instance from '../instance'; +import { BaseResponse } from '../../types/BaseResponse'; +import { LoginSuccess } from '../../types/auth/login'; +import { ResponseCode } from '../../types/enum/ResponseCode'; +import useRegisterStore from '../../stores/registerStore'; +import { useNavigate } from 'react-router-dom'; + +export const useProfileUpdateMutation = (prevUrl: string) => { + const { setLogIn, setIsIdDuplicate } = useRegisterStore(); + const navigate = useNavigate(); + + const mutation = useMutation({ + mutationFn: async (data: FormData) => { + return await instance.patch>( + `/user`, + data, + { + headers: { 'Content-Type': 'multipart/form-data' }, + }, + ); + }, + onSuccess: (response) => { + const responseData = response.data; + + if (responseData.code === ResponseCode.SUCCESS) { + console.log('프로필 업데이트 성공!'); + + const profileId = responseData.result.profileId; + const imgUrl = responseData.result.imgUrl; + const accessToken = responseData.result.accessToken; + setLogIn(profileId, imgUrl, accessToken); + + instance.defaults.headers.common['Authorization'] = + `Bearer ${accessToken}`; // 로그인된 유저에 대하여 모든 API 호출에 accessToken 포함시키는 코드 + + navigate(prevUrl); + return; + } + if (responseData.code === ResponseCode.ALREADY_EXIST_PROFILE_ID) { + // 중복된 profileId인 경우 + console.log('사용 중인 아이디'); + setIsIdDuplicate(true); + navigate(`${prevUrl + '?authState=signup'}`); + return; + } else { + // 프로필 업데이트 오류 + console.log('프로필 업데이트 실패'); + navigate(`${prevUrl === '/' ? prevUrl : prevUrl + '?authState=login'}`); + return; + } + }, + onError: () => { + console.log('프로필 업데이트 실패'); + navigate(prevUrl); + }, + }); + + return mutation; +}; + +export default useProfileUpdateMutation; diff --git a/src/apis/follow/getFollowing.tsx b/src/apis/follow/getFollowing.tsx index 2771238..864e74b 100644 --- a/src/apis/follow/getFollowing.tsx +++ b/src/apis/follow/getFollowing.tsx @@ -4,7 +4,7 @@ import { BaseResponse } from "../../types/BaseResponse"; export const getFollowing = async () => { try{ - const response = await instance.get>('following') + const response = await instance.get>('/following') console.log('response', response) return response.data.result || undefined } catch (error) { diff --git a/src/apis/follow/useGetFollowing.tsx b/src/apis/follow/useGetFollowing.tsx index 636bd97..59f4485 100644 --- a/src/apis/follow/useGetFollowing.tsx +++ b/src/apis/follow/useGetFollowing.tsx @@ -4,7 +4,9 @@ import { FollowingType } from "../../types/follow/FollowingType"; export const fetchFollowing = async (token:string| undefined): Promise => { try { if(token) { - return await getFollowing(); + const result = await getFollowing(); + console.log(result) + return result; } else { return undefined; } diff --git a/src/apis/mapData/followingMap.tsx b/src/apis/mapData/followingMap.tsx index 1997b1e..0429b30 100644 --- a/src/apis/mapData/followingMap.tsx +++ b/src/apis/mapData/followingMap.tsx @@ -5,6 +5,7 @@ import { BaseResponse } from "../../types/BaseResponse"; export const followingMap = async () => { try { const response = await instance.get>('/home/map'); + console.log(response) return response.data.result; } catch (error) { console.error('Error fetching data:',error); diff --git a/src/components/explore/MapKeywordCard.tsx b/src/components/explore/MapKeywordCard.tsx index 5b61797..3ed160c 100644 --- a/src/components/explore/MapKeywordCard.tsx +++ b/src/components/explore/MapKeywordCard.tsx @@ -4,6 +4,7 @@ import ico_carousel_backward from '../../assets/ico_carousel_backward.svg'; import ico_carousel_forward from '../../assets/ico_carousel_forward.svg'; import { getKeywordMap } from '../../apis/keywords/getKeywordMap'; import { KeywordMapType } from '../../types/keywords/KeywordMapType'; +import { Link } from 'react-router-dom'; interface MapKeywordCardProps { keyword: string; @@ -11,18 +12,24 @@ interface MapKeywordCardProps { isSelect: boolean; } -const MapKeywordCard: React.FC = ({ keyword, isSelect, mapId }) => { +const MapKeywordCard: React.FC = ({ + keyword, + isSelect, + mapId, +}) => { const INIT_RENDER = 4; const MAP_PER_PAGE = 3; const [renderKeyword, setRenderKeyword] = useState(INIT_RENDER); - const [keywordMap, setKeywordMap] = useState(undefined); + const [keywordMap, setKeywordMap] = useState( + undefined, + ); const handleForward = () => { - setRenderKeyword(prev => prev - MAP_PER_PAGE); + setRenderKeyword((prev) => prev - MAP_PER_PAGE); }; const handleBackward = () => { - setRenderKeyword(prev => prev + MAP_PER_PAGE); + setRenderKeyword((prev) => prev + MAP_PER_PAGE); }; const fetchKeywordMap = async () => { @@ -55,16 +62,20 @@ const MapKeywordCard: React.FC = ({ keyword, isSelect, mapI Backward - {isSelect && mapId && keywordMap?.maps - .slice(renderKeyword - INIT_RENDER, renderKeyword) - .map((map, index) => ( -
- -
- {map.mapTitle} + {isSelect && + mapId && + keywordMap?.maps + .slice(renderKeyword - INIT_RENDER, renderKeyword) + .map((map, index) => ( +
+ + + +
+ {map.mapTitle} +
-
- ))} + ))}
); }; diff --git a/src/components/explore/MapList.module.scss b/src/components/explore/MapList.module.scss index 4183ca1..ea122d2 100644 --- a/src/components/explore/MapList.module.scss +++ b/src/components/explore/MapList.module.scss @@ -10,8 +10,9 @@ .Images { display: flex; flex-direction: column; - width: 492px; + height: 100%; + width: 492px; border-radius: 6px; border: 1px solid#EBEEF2; @@ -19,6 +20,7 @@ .mapImg { width: 100%; + height: 216px; border-bottom: 1px solid#EBEEF2; } diff --git a/src/components/explore/MapList.tsx b/src/components/explore/MapList.tsx index 11a728d..0b5ded0 100644 --- a/src/components/explore/MapList.tsx +++ b/src/components/explore/MapList.tsx @@ -41,9 +41,11 @@ const MapList: React.FC = ({ map, keywordMap }) => { to={`/map/${mapItem.mapTitle}/view`} style={{ textDecoration: 'none' }} > -
- Map -
+ Map
= ({ map, keywordMap }) => {
Map diff --git a/src/components/global/GlobalNavigationBar.module.scss b/src/components/global/GlobalNavigationBar.module.scss index 953d414..53375ab 100644 --- a/src/components/global/GlobalNavigationBar.module.scss +++ b/src/components/global/GlobalNavigationBar.module.scss @@ -2,7 +2,6 @@ display: flex; z-index: 10; width: 72px; - overflow: hidden; } .LeftSideBar { diff --git a/src/components/global/GlobalNavigationBar.tsx b/src/components/global/GlobalNavigationBar.tsx index dd59a5d..6647251 100644 --- a/src/components/global/GlobalNavigationBar.tsx +++ b/src/components/global/GlobalNavigationBar.tsx @@ -45,7 +45,6 @@ const GlobalNavigationBar = (props: { children?: React.ReactNode }) => { console.log('setDimmed(true'); } else { setIsLog(true); - setIsOverlayVisible(false); console.log('setDimmed(false)'); } }, [loginNeeded, registerStatus]); diff --git a/src/components/map/BaseMap/BaseMap.tsx b/src/components/map/BaseMap/BaseMap.tsx index 5f43c85..5a9d969 100644 --- a/src/components/map/BaseMap/BaseMap.tsx +++ b/src/components/map/BaseMap/BaseMap.tsx @@ -1,11 +1,22 @@ -import React, { useEffect, useRef, useState } from 'react'; +import { getTsid } from 'tsid-ts'; +import React, { useEffect, useRef, useState, useCallback } from 'react'; import ReactDOMServer from 'react-dom/server'; -import { Map, DrawingManager, MapMarker, Polyline } from 'react-kakao-maps-sdk'; +import { + Map, + DrawingManager, + MapMarker, + Polyline, + useMap, + Polygon, +} from 'react-kakao-maps-sdk'; import useKakaoLoader from '../../../hooks/useKakaoLoader'; import styles from './BaseMap.module.scss'; import EditDesignPanel from './EditDesignPanel'; import { ReactComponent as DotThick } from '../../../assets/map/ico_dot_thick_custom.svg'; import { ReactComponent as DotThin } from '../../../assets/map/ico_dot_thin_custom.svg'; +import useMapInfoStore from '../../../stores/mapInfoStore'; +import { MapObject } from '../../../types/map/object/ObjectInfo'; +import { ObjectShape } from '../../../types/enum/ObjectShape'; interface BaseMapProps { mode: string; @@ -26,6 +37,32 @@ interface DrawingObjects { polygon?: kakao.maps.drawing.DrawingPolylineData[]; } +const useThrottle = any>( + func: T, + delay: number, +): T => { + const timeoutRef = useRef(null); + const lastRanRef = useRef(0); + + return useCallback( + (...args: Parameters) => { + const now = Date.now(); + + if (now - lastRanRef.current >= delay) { + func(...args); + lastRanRef.current = now; + } else if (!timeoutRef.current) { + timeoutRef.current = window.setTimeout(() => { + func(...args); + lastRanRef.current = Date.now(); + timeoutRef.current = null; + }, delay); + } + }, + [func, delay], + ) as T; +}; + const BaseMap: React.FC = ({ mode }) => { useKakaoLoader(); @@ -36,8 +73,6 @@ const BaseMap: React.FC = ({ mode }) => { lng: 127.08278172427, }); - const [marker, setMarker] = useState(null); - const [objects, setObjects] = useState>({}); const [isObject, setIsObject] = useState(''); const [strokeWeight, setStrokeWeight] = useState(1.5); const [dot, setDot] = useState(''); // 저장할 데이터는 Base64 문자열 @@ -46,6 +81,8 @@ const BaseMap: React.FC = ({ mode }) => { const [isShare, setIsShare] = useState(false); const [selectedMarker, setSelectedMarker] = useState(null); // 마커 지우기 위해서 사용 + const { innerData, doc, selectedObjectId, setSelectedObjectId } = + useMapInfoStore(); const managerRef = useRef< @@ -158,25 +195,62 @@ const BaseMap: React.FC = ({ mode }) => { }, [dotColor, dotShape, isObject]); const getMarker = (position: Position) => { - const pre = marker; - if (pre) { - setMarker([...pre, { img: dot, pos: position }]); - } else { - setMarker([{ img: dot, pos: position }]); - } + const id = getTsid().toString(); + doc?.update((root) => { + root.objects.push({ + objectId: id, + type: ObjectShape.POINT, + name: ObjectShape.POINT, + shape: { + img: dot, + pos: position, + }, + geoAttribute: {}, + userAttribute: {}, + }); + }, `Add object ${id}(${ObjectShape.POINT})`); setIsObject(''); setDotColor('#111111'); setDotShape('dot thin'); }; const manager = managerRef.current; - useEffect(() => { - const manager = managerRef.current; - manager?.addListener('drawend', () => { - const objects = manager?.getOverlays(['polyline', 'polygon']); - setIsObject(''); - setObjects(objects); + manager?.addListener('drawend', (event) => { + const objectType = event.overlayType; + const datas = manager?.getData([objectType])[objectType]; + const overlays = manager?.getOverlays([objectType])[objectType]; + + const id = getTsid().toString(); + const lastIndex = datas.length - 1; + if (objectType === 'polyline' || 'polygon') { + const objectShape = datas[lastIndex]; + let geoAttribute = {}; + + if (objectType === 'polyline') { + // @ts-ignore 카카오맵 라이브러리 이슈 + geoAttribute = { length: overlays[lastIndex].getLength() }; + } else if (objectType === 'polygon') { + geoAttribute = { + // @ts-ignore 카카오맵 라이브러리 이슈 + perimeter: overlays[lastIndex].getLength(), + // @ts-ignore 카카오맵 라이브러리 이슈 + area: overlays[lastIndex].getArea(), + }; + } + + doc?.update((root) => { + root.objects.push({ + objectId: id, + type: objectType, + name: objectType, + shape: objectShape, + geoAttribute: geoAttribute, + userAttribute: {}, + }); + }, `Add object ${id}(${objectType})`); + } + manager.setStrokeWeight(1.5); manager.setStrokeColor('#111111'); manager.setStyle( @@ -189,71 +263,55 @@ const BaseMap: React.FC = ({ mode }) => { 'fillOpacity', 0.2, ); - }); // 그리기 끝나면 => objects 안에 넣기 - - manager?.addListener('remove', () => { - const objects = manager?.getOverlays(['polyline', 'polygon']); - setObjects(objects); - }); // 제거되면 남아있는 객체 정보로 업데이트 - }, [manager, objects]); + manager.remove(event.target); + }); + }, [manager]); useEffect(() => { - if ( - (Array.isArray(objects.polygon) && objects.polygon?.length > 0) || - (Array.isArray(objects.polyline) && objects.polyline?.length > 0) || - (marker !== undefined && marker !== null && marker.length > 0) - ) { + if (innerData.objects && innerData.objects.length > 0) { setIsShare(true); } else { setIsShare(false); } - }, [objects, marker]); - - let select: kakao.maps.drawing.ExtendsOverlay | null = null; + }, [innerData.objects]); - // 전역에서 keydown 이벤트 리스너를 등록 - window.addEventListener('keydown', (ev: KeyboardEvent) => { - if (ev.key === 'Delete' && select) { - manager?.remove(select); - select = null; - } else if (ev.key === 'Delete' && selectedMarker) { - setMarker((pre) => { - return (pre || []).filter( - (marker) => - marker.pos.lat !== selectedMarker.getPosition().getLat() || - marker.pos.lng !== selectedMarker.getPosition().getLng(), + const handleDeleteKey = useThrottle((ev: KeyboardEvent) => { + if ( + (ev.key === 'Delete' || (ev.key === 'Backspace' && ev.metaKey)) && + selectedObjectId + ) { + doc?.update((root) => { + const indexToDelete = root.objects.findIndex( + (obj: MapObject) => obj.objectId === selectedObjectId, ); - }); - setIsObject(''); - setSelectedMarker(null); + + if (indexToDelete !== -1) { + root.objects.splice(indexToDelete, 1); + setSelectedObjectId(undefined); + } + }, `Delete object ${selectedObjectId}`); } - }); + }, 300); - // drawend 이벤트 리스너 등록 - manager?.addListener('drawend', (e: kakao.maps.drawing.MouseEvent) => { - const object = e.target; + useEffect(() => { + document.addEventListener('keydown', handleDeleteKey); + return () => { + document.removeEventListener('keydown', handleDeleteKey); + }; + }, [handleDeleteKey]); - // 클릭 이벤트 리스너 등록 - kakao.maps.event.addListener(object, 'click', () => { - select = object; - }); + window.addEventListener('keydown', (ev: KeyboardEvent) => { + if (ev.key === 'Escape' && selectedObjectId) { + setSelectedObjectId(""); + } }); - useEffect(() => { - window.addEventListener('keydown', (ev: KeyboardEvent) => { - if (ev.key === 'Delete' && selectedMarker) { - selectedMarker.setMap(null); - setMarker((pre) => { - return (pre || []).filter( - (marker) => - marker.pos.lat !== selectedMarker.getPosition().getLat() || - marker.pos.lng !== selectedMarker.getPosition().getLng(), - ); - }); - setSelectedMarker(null); - } - }); - }, [marker, selectedMarker]); + function pointsToPath(points: Array<{ x: number; y: number }>) { + return points.map((point) => ({ + lat: point.y, + lng: point.x, + })); + } return ( <> @@ -266,26 +324,51 @@ const BaseMap: React.FC = ({ mode }) => { if (isObject === 'dot') { const latlng = mouseEvent.latLng; getMarker({ lat: latlng.getLat(), lng: latlng.getLng() }); - // setIsObject('') } }} > - {marker?.map((item) => ( - { - setSelectedMarker(marker); - }} - /> - ))} + {innerData.objects?.map((object: MapObject) => { + if (object.type === ObjectShape.POINT) { + return ( + setSelectedObjectId(object.objectId)} + /> + ); + } else if (object.type === ObjectShape.LINE) { + return ( + { + console.log('mouseover', target, mouseEvent); + }} + onClick={() => setSelectedObjectId(object.objectId)} + /> + ); + } else if (object.type === ObjectShape.PLANE) { + return ( + setSelectedObjectId(object.objectId)} + /> + ); + } + })} = ({ mode }) => { polylineOptions={{ draggable: false, removable: false, - editable: true, + editable: false, strokeWeight: strokeWeight, strokeColor: '#111111', hintStrokeStyle: 'dash', @@ -305,7 +388,7 @@ const BaseMap: React.FC = ({ mode }) => { polygonOptions={{ draggable: false, removable: false, - editable: true, + editable: false, strokeColor: '#111111', strokeWeight: strokeWeight, fillColor: '#111111', diff --git a/src/components/map/MapInfoPanel/MapInfoPanel.tsx b/src/components/map/MapInfoPanel/MapInfoPanel.tsx index 7e8b32a..571cfcb 100644 --- a/src/components/map/MapInfoPanel/MapInfoPanel.tsx +++ b/src/components/map/MapInfoPanel/MapInfoPanel.tsx @@ -1,4 +1,3 @@ -import { useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import styles from './MapInfoPanel.module.scss'; import MapProducerConatiner from './MapBasicInfo/MapProducerContainer/MapProducerContainer'; @@ -8,6 +7,7 @@ import { MapMode } from '../../../types/enum/MapMode'; import BlackBackBtn from '../../../assets/btn_arrow_left_black.svg'; import useRegisterStore from '../../../stores/registerStore'; import { useMapBasicInfoQuery } from '../../../apis/Map/fetchMapBasicInfo'; +import useMapInfoStore from '../../../stores/mapInfoStore'; interface Props { mode: MapMode; diff --git a/src/components/map/MapInfoPanel/ObjectOutlineList/ObjectList.tsx b/src/components/map/MapInfoPanel/ObjectOutlineList/ObjectList.tsx index 540f36b..e1f706c 100644 --- a/src/components/map/MapInfoPanel/ObjectOutlineList/ObjectList.tsx +++ b/src/components/map/MapInfoPanel/ObjectOutlineList/ObjectList.tsx @@ -10,7 +10,7 @@ interface Props { } const ObjectList: React.FC = ({ mode, mapId }) => { - const { objectOutlineList } = useMapInfoStore(); + const { innerData } = useMapInfoStore(); const { mapBasicInfo } = useMapBasicInfoQuery(mapId, mode); return ( @@ -25,9 +25,9 @@ const ObjectList: React.FC = ({ mode, mapId }) => { : `${styles.objectList} ${styles.notMineList}` } > - {objectOutlineList && - objectOutlineList.map((object) => ( - + {innerData.objects && + innerData.objects.map((object) => ( + ))}
diff --git a/src/components/map/MapInfoPanel/ObjectOutlineList/ObjectOutlineBtn.tsx b/src/components/map/MapInfoPanel/ObjectOutlineList/ObjectOutlineBtn.tsx index 7fdd97f..ae7158d 100644 --- a/src/components/map/MapInfoPanel/ObjectOutlineList/ObjectOutlineBtn.tsx +++ b/src/components/map/MapInfoPanel/ObjectOutlineList/ObjectOutlineBtn.tsx @@ -1,20 +1,26 @@ import styles from './ObjectOutlineBtn.module.scss'; -import { ObjectOutline } from '../../../../types/map/object/ObjectOutline'; +import { MapObject } from '../../../../types/map/object/ObjectInfo'; import { ObjectShape } from '../../../../types/enum/ObjectShape'; import Point from '../../../../assets/map/ico_point_gray.svg'; import Line from '../../../../assets/map/ico_line_gray.svg'; import Plane from '../../../../assets/map/ico_plane_gray.svg'; +import useMapInfoStore from '../../../../stores/mapInfoStore'; interface Props { - object: ObjectOutline; + object: MapObject; } const ObjectOutlineBtn: React.FC = ({ object }) => { + const { setSelectedObjectId } = useMapInfoStore(); return ( -
-
+ {/*
상세 주소