diff --git a/frontend/src/component/canvasWithMap/canvasWithMapforDraw/MapCanvasForDraw.tsx b/frontend/src/component/canvasWithMap/canvasWithMapforDraw/MapCanvasForDraw.tsx
index f1955730..82320089 100644
--- a/frontend/src/component/canvasWithMap/canvasWithMapforDraw/MapCanvasForDraw.tsx
+++ b/frontend/src/component/canvasWithMap/canvasWithMapforDraw/MapCanvasForDraw.tsx
@@ -11,6 +11,7 @@ import startmarker from '@/assets/startmarker.png';
import endmarker from '@/assets/endmarker.png';
import { CurrentUserContext } from '@/context/CurrentUserContext';
import { ToolDescription } from '@/component/tooldescription/ToolDescription';
+import { SearchBox } from '@/component/searchbox/SearchBox';
export const MapCanvasForDraw = ({
width,
@@ -216,9 +217,27 @@ export const MapCanvasForDraw = ({
if (!clickedPoint) return;
switch (toolType) {
case ButtonState.START_MARKER:
+ setCurrentUser(prevUser => ({
+ ...prevUser,
+ start_location: {
+ ...prevUser.start_location,
+ title: '', // title을 빈 문자열로 초기화 -> 검색창에 보이게 하려고
+ lat: clickedPoint.lat,
+ lng: clickedPoint.lng,
+ },
+ }));
setStartMarker(clickedPoint);
break;
case ButtonState.DESTINATION_MARKER:
+ setCurrentUser(prevUser => ({
+ ...prevUser,
+ end_location: {
+ ...prevUser.end_location,
+ title: '', // title을 빈 문자열로 초기화 -> 검색창에 보이게 하려고
+ lat: clickedPoint.lat,
+ lng: clickedPoint.lng,
+ },
+ }));
setEndMarker(clickedPoint);
break;
case ButtonState.LINE_DRAWING:
@@ -384,6 +403,33 @@ export const MapCanvasForDraw = ({
}
};
+ const handleCreateMarker = (point: IPoint) => {
+ if (toolType === ButtonState.START_MARKER) {
+ setStartMarker(point);
+ setCurrentUser(prevUser => ({
+ ...prevUser,
+ start_location: {
+ ...prevUser.start_location,
+ title: '',
+ },
+ }));
+ } else {
+ setEndMarker(point);
+ setCurrentUser(prevUser => ({
+ ...prevUser,
+ end_location: {
+ ...prevUser.end_location,
+ title: '',
+ },
+ }));
+ }
+ };
+
+ const handleDeleteMarker = () => {
+ if (toolType === ButtonState.START_MARKER) setStartMarker(null);
+ else setEndMarker(null);
+ };
+
useEffect(() => {
if (isDragging) {
if (canvasRef.current) {
@@ -415,6 +461,16 @@ export const MapCanvasForDraw = ({
onTouchMove={handleTouchMove}
onTouchEnd={handleTouchEnd}
>
+ {(toolType === ButtonState.START_MARKER || toolType === ButtonState.DESTINATION_MARKER) && (
+
+
+
+ )}
{toolType === ButtonState.LINE_DRAWING ? (
diff --git a/frontend/src/component/header/Header.tsx b/frontend/src/component/header/Header.tsx
index a58bf15c..61d68d5c 100644
--- a/frontend/src/component/header/Header.tsx
+++ b/frontend/src/component/header/Header.tsx
@@ -23,7 +23,7 @@ export const Header = (props: IHeaderProps) => {
return (
diff --git a/frontend/src/component/routebutton/RouteResultButton.tsx b/frontend/src/component/routebutton/RouteResultButton.tsx
index 7eb075a1..59cf11e7 100644
--- a/frontend/src/component/routebutton/RouteResultButton.tsx
+++ b/frontend/src/component/routebutton/RouteResultButton.tsx
@@ -28,11 +28,11 @@ export const RouteResultButton = (props: IRouteResultButtonProps) => {
props.user.id > 1 ? '' : 'mr-8',
)}
>
-
- {props.user.start_location.title}
+
+ {props.user.end_location.title}
-
+
{props.user.end_location.title}
diff --git a/frontend/src/component/searchbox/SearchBox.tsx b/frontend/src/component/searchbox/SearchBox.tsx
index e119c66d..95fd8a4b 100644
--- a/frontend/src/component/searchbox/SearchBox.tsx
+++ b/frontend/src/component/searchbox/SearchBox.tsx
@@ -1,19 +1,27 @@
import { ToolTypeContext } from '@/context/ToolTypeContext';
import React, { useContext, useEffect, useState } from 'react';
-import { IoMdClose, IoMdSearch } from 'react-icons/io';
+import { IoMdClose } from 'react-icons/io';
import { CurrentUserContext } from '@/context/CurrentUserContext';
+import { IPoint } from '@/lib/types/canvasInterface';
+import { getAddressFromCoordinates } from '@/utils/map/getAddress';
import { ButtonState } from '../common/enums';
interface ISearchResultItem {
title: string;
address: string;
- link: string;
+ roadAddress: string;
lat: number;
lng: number;
}
-export const SearchBox = () => {
- const [inputValue, setInputValue] = useState(''); // 검색 입력값 상태
+interface ISearchBoxProps {
+ startMarker?: IPoint | null;
+ endMarker?: IPoint | null;
+ setMarker: (point: IPoint) => void;
+ deleteMarker: () => void;
+}
+export const SearchBox = (props: ISearchBoxProps) => {
+ const [inputValue, setInputValue] = useState
(''); // 검색 입력값 상태
const [searchResults, setSearchResults] = useState([]); // 검색 결과 상태
const [loading, setLoading] = useState(false); // 로딩 상태
const [error, setError] = useState(null); // 에러 상태
@@ -68,8 +76,8 @@ export const SearchBox = () => {
title: item.title.replace(/<\/?[^>]+(>|$)/g, ''), // HTML 태그 제거
address: item.address || item.roadAddress || '주소 정보 없음',
link: item.link || '#',
- lat: parseFloat(item.mapy) / 1e7, // 위도 값 변환
- lng: parseFloat(item.mapx) / 1e7, // 경도 값 변환
+ lat: parseFloat(item.mapy) / 1e7,
+ lng: parseFloat(item.mapx) / 1e7,
}));
console.log(data);
setSearchResults(formattedResults); // 검색 결과 상태 업데이트
@@ -83,45 +91,79 @@ export const SearchBox = () => {
/* TODO: 자동검색 로직 수정 필요 */
useEffect(() => {
- const delayDebounceFn = setTimeout(() => {
- if (inputValue.trim()) {
- handleSearch();
+ const getAddress = async () => {
+ if (toolType === ButtonState.START_MARKER && props.startMarker) {
+ if (currentUser.start_location?.title) {
+ // title이 비어있을 때 === 부산역 같은 title이 없을때
+ return;
+ }
+ const value = await getAddressFromCoordinates(props.startMarker.lat, props.startMarker.lng);
+ setInputValue(value);
+ } else if (toolType === ButtonState.DESTINATION_MARKER && props.endMarker) {
+ if (currentUser.end_location?.title) {
+ return;
+ }
+ const value = await getAddressFromCoordinates(props.endMarker.lat, props.endMarker.lng);
+ setInputValue(value);
}
- }, 300);
+ };
- return () => clearTimeout(delayDebounceFn);
- }, [inputValue]);
+ getAddress();
+ }, [toolType, props.startMarker, props.endMarker]);
const handleInputChange = (event: React.ChangeEvent) => {
setInputValue(event.target.value); // 상태 업데이트
};
+ useEffect(() => {
+ // 마커가 이미 존재하는 경우 더 이상 검색하지 않도록 방지
+ if (toolType === ButtonState.START_MARKER && props.startMarker) {
+ return;
+ }
+
+ if (toolType === ButtonState.DESTINATION_MARKER && props.endMarker) {
+ return;
+ }
+
+ if (inputValue.trim()) {
+ const delayDebounceFn = setTimeout(() => {
+ handleSearch();
+ }, 300);
+
+ // Todo : 요부분 반환값 lint 오류 때문에 해결이 안돼요...
+ // eslint-disable-next-line consistent-return
+ return () => {
+ clearTimeout(delayDebounceFn);
+ };
+ }
+ }, [inputValue, props.startMarker, props.endMarker, toolType]);
+
const handleSelectResult = (result: ISearchResultItem) => {
- setInputValue(result.title); // 선택한 결과로 inputValue를 업데이트
- setSearchResults([]); // 결과 리스트를 닫음
+ setInputValue(result.title);
+ setSearchResults([]);
+ props.setMarker({ lat: result.lat, lng: result.lng });
updateUser(result.title, result.lat, result.lng);
- console.log(`위도: ${result.lat}, 경도: ${result.lng}`);
};
const handleClear = () => {
- setInputValue(''); // 입력값 초기화
- setSearchResults([]); // 검색 결과 초기화
+ setInputValue('');
+ setSearchResults([]);
+ props.deleteMarker();
};
return (
-
+
{/* 검색 입력 */}
-
+
-
@@ -135,7 +177,7 @@ export const SearchBox = () => {
{searchResults.map(result => (