+
+
+
+ setIsActive(true)}
+ onStop={() => setIsActive(false)}
+ onUndo={undoMarker}
+ onReset={resetMarkers}
+ onCopy={copyMarkers}
+ />
);
};
diff --git a/apps/nowait-user/src/pages/waiting/BoothMapManage/components/GeoDataForm.tsx b/apps/nowait-user/src/pages/waiting/BoothMapManage/components/GeoDataForm.tsx
new file mode 100644
index 00000000..9d6a51ca
--- /dev/null
+++ b/apps/nowait-user/src/pages/waiting/BoothMapManage/components/GeoDataForm.tsx
@@ -0,0 +1,40 @@
+import { Button } from "@repo/ui";
+import { useState } from "react";
+
+const GeoDataForm = () => {
+ const [geoData, setGeoData] = useState("");
+
+ const copyPolygon = () => {
+ const parsed = JSON.parse(geoData);
+ const polygon = [
+ parsed.map(({ lat, lon }: { lat: number; lon: number }) => [
+ lon,
+ lat,
+ ]),
+ ];
+
+ navigator.clipboard.writeText(JSON.stringify(polygon, null, 2));
+ alert("복사가 완료 되었습니다.");
+ };
+
+ return (
+
+
+
+ );
+};
+
+export default GeoDataForm;
\ No newline at end of file
diff --git a/apps/nowait-user/src/pages/waiting/BoothMapManage/components/MapCanvas.tsx b/apps/nowait-user/src/pages/waiting/BoothMapManage/components/MapCanvas.tsx
new file mode 100644
index 00000000..c1f3eaf8
--- /dev/null
+++ b/apps/nowait-user/src/pages/waiting/BoothMapManage/components/MapCanvas.tsx
@@ -0,0 +1,26 @@
+import { Container as MapDiv, Marker, NaverMap } from "react-naver-maps";
+import UniversityPolygon from "../../boothMap/components/UniversityPolygon";
+import MapControlButtons from "../../boothMap/components/mapControls/MapControls";
+
+interface PropsType {
+ center: { lat: number; lng: number };
+ paths: any;
+ markers: { storeId: string; lat: number; lng: number }[];
+}
+
+const MapCanvas = ({ center, paths, markers }: PropsType) => {
+ return (
+
+
+
+
+
+ {markers.map(({ storeId, lat, lng }) => (
+
+ ))}
+
+
+ );
+};
+
+export default MapCanvas;
diff --git a/apps/nowait-user/src/pages/waiting/BoothMapManage/components/MapControls.tsx b/apps/nowait-user/src/pages/waiting/BoothMapManage/components/MapControls.tsx
new file mode 100644
index 00000000..bddca09d
--- /dev/null
+++ b/apps/nowait-user/src/pages/waiting/BoothMapManage/components/MapControls.tsx
@@ -0,0 +1,33 @@
+import { Button } from "@repo/ui";
+
+type Props = {
+ isActive: boolean;
+ hasMarkers: boolean;
+ onStart: () => void;
+ onStop: () => void;
+ onUndo: () => void;
+ onReset: () => void;
+ onCopy: () => void;
+};
+
+const MapControls = ({
+ isActive,
+ hasMarkers,
+ onStart,
+ onStop,
+ onUndo,
+ onReset,
+ onCopy,
+}: Props) => {
+ return (
+
+
+
+
+
+
+
+ );
+};
+
+export default MapControls;
\ No newline at end of file
diff --git a/apps/nowait-user/src/pages/waiting/BoothMapManage/hooks/useMapClick.ts b/apps/nowait-user/src/pages/waiting/BoothMapManage/hooks/useMapClick.ts
new file mode 100644
index 00000000..1d4695da
--- /dev/null
+++ b/apps/nowait-user/src/pages/waiting/BoothMapManage/hooks/useMapClick.ts
@@ -0,0 +1,26 @@
+import { useEffect } from "react";
+
+interface PropsType {
+ map: any | null;
+ enabled: boolean;
+ onClick: (lat: number, lng: number) => void;
+};
+
+export const useMapClick = ({ map, enabled, onClick }: PropsType) => {
+ useEffect(() => {
+ if (!map) return;
+
+ const listener = window.naver.maps.Event.addListener(
+ map,
+ "click",
+ (e: any) => {
+ if (!enabled) return;
+ onClick(e.coord.lat(), e.coord.lng());
+ }
+ );
+
+ return () => {
+ window.naver.maps.Event.removeListener(listener);
+ };
+ }, [map, enabled, onClick]);
+};
\ No newline at end of file
diff --git a/apps/nowait-user/src/pages/waiting/BoothMapManage/hooks/useMarkerManager.ts b/apps/nowait-user/src/pages/waiting/BoothMapManage/hooks/useMarkerManager.ts
new file mode 100644
index 00000000..9e5e3f89
--- /dev/null
+++ b/apps/nowait-user/src/pages/waiting/BoothMapManage/hooks/useMarkerManager.ts
@@ -0,0 +1,56 @@
+import { useCallback, useState } from "react";
+
+export const useMarkerManager = () => {
+ const [markers, setMarkers] = useState<{ storeId: string; lat: number; lng: number }[]>([]);
+ const [isActive, setIsActive] = useState(false);
+
+ //마커 추가
+ const addMarker = useCallback(
+ (lat: number, lng: number) => {
+ const storeId = prompt("스토어 아이디를 입력하세요");
+ if (!storeId?.trim()) return;
+
+ const isExist = markers.some(
+ (marker) => marker.storeId === storeId
+ );
+
+ if (isExist) {
+ alert("이미 존재하는 주점입니다.");
+ return;
+ }
+
+ setMarkers((prev) => [...prev, { storeId, lat, lng }]);
+ },
+ [markers]
+ );
+
+ //마커 뒤로가기
+ const undoMarker = () =>
+ setMarkers((prev) => prev.slice(0, -1));
+
+ //마커 초기화
+ const resetMarkers = () => setMarkers([]);
+
+ //전체 마커 복사
+ const copyMarkers = () => {
+ const text = markers
+ .map(
+ ({ storeId, lat, lng }) =>
+ `${storeId} : { lat: ${lat}, lng: ${lng} }`
+ )
+ .join(",\n");
+
+ navigator.clipboard.writeText(text);
+ alert("복사가 완료 되었습니다.");
+ };
+
+ return {
+ markers,
+ isActive,
+ setIsActive,
+ addMarker,
+ undoMarker,
+ resetMarkers,
+ copyMarkers,
+ };
+};
\ No newline at end of file
diff --git a/apps/nowait-user/src/pages/waiting/boothMap/MapPage.tsx b/apps/nowait-user/src/pages/waiting/boothMap/MapPage.tsx
index 525d0197..09124398 100644
--- a/apps/nowait-user/src/pages/waiting/boothMap/MapPage.tsx
+++ b/apps/nowait-user/src/pages/waiting/boothMap/MapPage.tsx
@@ -8,7 +8,12 @@ import BoothMarkers from "./components/BoothMarkers";
import { useBooths } from "./hooks/useBooths";
import { useMyLocation } from "./hooks/useMyLocation";
import MapControlButtons from "./components/mapControls/MapControls";
-import { Container as MapDiv, NaverMap, Marker } from "react-naver-maps";
+import {
+ Container as MapDiv,
+ NaverMap,
+ Marker,
+ useMap,
+} from "react-naver-maps";
import { useMapZoom } from "./hooks/useMapZoom";
import { useMapEvents } from "./hooks/useMapEvents";
@@ -20,8 +25,7 @@ declare global {
const MapPage = () => {
const [selectedBooth, setSelectedBooth] = useState
(null);
- const [map, setMap] = useState(null);
-
+ const map = useMap();
// const { setIsCompassMode } = isCompassModeStore();
//대학교 폴리곤(영역) 설정
const paths = useGeoPolygon();
@@ -31,6 +35,7 @@ const MapPage = () => {
const myLocation = useMyLocation();
//줌레벨 가져오기
const zoom = useMapZoom(map);
+ // const isInsideServiceArea = useIsInsidePolygon(paths, myLocation.center);
//맵 드래그, 클릭 컨트롤
useMapEvents(map, () => setSelectedBooth(null));
@@ -42,7 +47,7 @@ const MapPage = () => {
setSelectedBooth(id);
}
},
- [selectedBooth]
+ [selectedBooth],
);
return (
@@ -56,12 +61,8 @@ const MapPage = () => {
height: "600px",
}}
>
-
-
+
+
{!myLocation.isLoading && }
void;
+}
+
+const BoothMarker = React.memo(
+ ({ booth, zoomLevel, openBooth }: BoothMarkerProps) => {
+ const isZoomed = zoomLevel >= 19;
+
+ const imageUrl =
+ booth.profileImage?.imageUrl &&
+ booth.profileImage.imageUrl.trim().length > 0
+ ? booth.profileImage.imageUrl
+ : DotMarker;
+
+ const icon = !isZoomed
+ ? {
+ url: DotMarker,
+ size: { width: 12, height: 12 },
+ scaledSize: { width: 12, height: 12 },
+ }
+ : {
+ content: `
+
+
+
+

+
+
+
+
+
+`,
+ size: { width: 44, height: 44 },
+ anchor: { x: 22, y: 22 },
+ };
+
+ return (
+ openBooth(booth.storeId)}
+ />
+ );
+ }
+);
+
+export default BoothMarker;
diff --git a/apps/nowait-user/src/pages/waiting/boothMap/components/BoothMarkers.tsx b/apps/nowait-user/src/pages/waiting/boothMap/components/BoothMarkers.tsx
index 77249211..3a9a1582 100644
--- a/apps/nowait-user/src/pages/waiting/boothMap/components/BoothMarkers.tsx
+++ b/apps/nowait-user/src/pages/waiting/boothMap/components/BoothMarkers.tsx
@@ -1,33 +1,19 @@
-// import BoothMarker from "../../../../assets/icon/BoothMarker.svg?url";
-import MarkerTest from "../../../../assets/markerTest2.svg?url"
-import DotMarker from "../../../../assets/icon/DotMarker.svg?url";
-import React from "react";
-import { Marker } from "react-naver-maps";
+import BoothMarker from "./BoothMarker";
-interface BoothMarkersProps {
- booths: { storeId: number; lat: number; lng: number }[];
- openBooth: (id: number) => void;
- zoomLevel: number;
-}
+const BoothMarkers = ({ booths, zoomLevel, openBooth }:any) => {
+ console.log(booths)
+ return (
+ <>
+ {booths.map((booth:any) => (
+
+ ))}
+ >
+ );
+};
-const BoothMarkers = React.memo(
- ({ booths, openBooth, zoomLevel }: BoothMarkersProps) => {
-
- return (
- <>
- {booths.map((booth) => (
- = 18 ? MarkerTest : DotMarker,
- }}
- onClick={() => openBooth(booth.storeId)}
- />
- ))}
- >
- );
- }
-);
-
-export default BoothMarkers;
+export default BoothMarkers;
\ No newline at end of file
diff --git a/apps/nowait-user/src/pages/waiting/boothMap/components/MapHeader.tsx b/apps/nowait-user/src/pages/waiting/boothMap/components/MapHeader.tsx
index a2a26c72..fbbf60a0 100644
--- a/apps/nowait-user/src/pages/waiting/boothMap/components/MapHeader.tsx
+++ b/apps/nowait-user/src/pages/waiting/boothMap/components/MapHeader.tsx
@@ -8,11 +8,11 @@ import Cancel from "../../../../assets/icon/cancel.svg?react";
import Portal from "../../../../components/common/modal/Portal";
import SearchModal from "../../../../components/common/modal/SearchModal";
-const HomeHeader = React.memo(() => {
+const MapHeader = React.memo(() => {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const [isSearchOpen, setIsSearchOpen] = useState(false);
const navigate = useNavigate();
- console.log("헤더 렌더링")
+
const toggleMenu = () => {
setIsMenuOpen(!isMenuOpen);
};
@@ -187,4 +187,4 @@ const HomeHeader = React.memo(() => {
);
});
-export default HomeHeader;
+export default MapHeader;
diff --git a/apps/nowait-user/src/pages/waiting/boothMap/components/UniversityPolygon.tsx b/apps/nowait-user/src/pages/waiting/boothMap/components/UniversityPolygon.tsx
index e9a8bd3e..a5eef6d6 100644
--- a/apps/nowait-user/src/pages/waiting/boothMap/components/UniversityPolygon.tsx
+++ b/apps/nowait-user/src/pages/waiting/boothMap/components/UniversityPolygon.tsx
@@ -10,10 +10,10 @@ const UniversityPolygon = ({
return (
);
diff --git a/apps/nowait-user/src/pages/waiting/boothMap/components/mapControls/CompassButton.tsx b/apps/nowait-user/src/pages/waiting/boothMap/components/mapControls/CompassButton.tsx
index b028ffe3..a07d8eb7 100644
--- a/apps/nowait-user/src/pages/waiting/boothMap/components/mapControls/CompassButton.tsx
+++ b/apps/nowait-user/src/pages/waiting/boothMap/components/mapControls/CompassButton.tsx
@@ -1,16 +1,15 @@
// import { useRef } from "react";
import MyLocation from "../../../../../assets/icon/myLocation.svg?react";
import { isCompassModeStore } from "../../../../../stores/mapStore";
-import { useNavermaps } from "react-naver-maps";
+import { useMap, useNavermaps } from "react-naver-maps";
const CompassButton = ({
- map,
center,
}: {
- map: any;
center: { lat: number; lng: number };
}) => {
const { isCompassMode, setIsCompassMode } = isCompassModeStore();
+ const map = useMap();
const navermaps = useNavermaps();
const handleClick = async () => {
diff --git a/apps/nowait-user/src/pages/waiting/boothMap/components/mapControls/MapControls.tsx b/apps/nowait-user/src/pages/waiting/boothMap/components/mapControls/MapControls.tsx
index bad40389..26b881c6 100644
--- a/apps/nowait-user/src/pages/waiting/boothMap/components/mapControls/MapControls.tsx
+++ b/apps/nowait-user/src/pages/waiting/boothMap/components/mapControls/MapControls.tsx
@@ -5,10 +5,8 @@ import UniversityListModal from "./UniversityListModal";
import CompassButton from "./CompassButton";
const MapControlButtons = ({
- map,
center,
}: {
- map: any
center: { lat: number; lng: number };
}) => {
const modal = useModal();
@@ -24,11 +22,11 @@ const MapControlButtons = ({
>
-
+