diff --git a/components/map/mapbox-map.tsx b/components/map/mapbox-map.tsx index e472c705..ab3fdd92 100644 --- a/components/map/mapbox-map.tsx +++ b/components/map/mapbox-map.tsx @@ -1,6 +1,7 @@ 'use client' -import { useEffect, useRef, useCallback } from 'react' // Removed useState +import { useEffect, useRef, useCallback } from 'react' +import { createRoot } from 'react-dom/client' import mapboxgl from 'mapbox-gl' import MapboxDraw from '@mapbox/mapbox-gl-draw' import * as turf from '@turf/turf' @@ -9,16 +10,20 @@ import 'react-toastify/dist/ReactToastify.css' import 'mapbox-gl/dist/mapbox-gl.css' import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css' import { useMapToggle, MapToggleEnum } from '../map-toggle-context' -import { useMapData } from './map-data-context'; // Add this import -import { useMapLoading } from '../map-loading-context'; // Import useMapLoading +import { useMapData } from './map-data-context' +import { useMapLoading } from '../map-loading-context' import { useMap } from './map-context' +import UserMarker from './user-marker' -mapboxgl.accessToken = process.env.NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN as string; +mapboxgl.accessToken = process.env.NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN as string -export const Mapbox: React.FC<{ position?: { latitude: number; longitude: number; } }> = ({ position }) => { +export const Mapbox: React.FC<{ + position?: { latitude: number; longitude: number } +}> = ({ position }) => { const mapContainer = useRef(null) const map = useRef(null) const { setMap } = useMap() + const userMarkerRef = useRef(null) const drawRef = useRef(null) const rotationFrameRef = useRef(null) const polygonLabelsRef = useRef<{ [id: string]: mapboxgl.Marker }>({}) @@ -199,39 +204,55 @@ export const Mapbox: React.FC<{ position?: { latitude: number; longitude: number } }, [stopRotation]) - const updateMapPosition = useCallback(async (latitude: number, longitude: number) => { - if (map.current && !isUpdatingPositionRef.current) { - isUpdatingPositionRef.current = true - stopRotation() - - try { - // Update our current map center ref - currentMapCenterRef.current.center = [longitude, latitude] - - await new Promise((resolve) => { - map.current?.flyTo({ - center: [longitude, latitude], - zoom: 12, - essential: true, - speed: 0.5, - curve: 1, - }) - map.current?.once('moveend', () => { - resolve() - }) - }) - setTimeout(() => { - if (mapType === MapToggleEnum.RealTimeMode) { - startRotation() + const updateMapPosition = useCallback( + async (latitude: number, longitude: number) => { + if (map.current && !isUpdatingPositionRef.current) { + isUpdatingPositionRef.current = true + stopRotation() + + try { + currentMapCenterRef.current.center = [longitude, latitude] + + if (userMarkerRef.current) { + userMarkerRef.current.setLngLat([longitude, latitude]) + } else { + const markerElement = document.createElement('div') + const root = createRoot(markerElement) + root.render() + userMarkerRef.current = new mapboxgl.Marker({ + element: markerElement + }) + .setLngLat([longitude, latitude]) + .addTo(map.current) } + + await new Promise(resolve => { + map.current?.flyTo({ + center: [longitude, latitude], + zoom: 12, + essential: true, + speed: 0.5, + curve: 1 + }) + map.current?.once('moveend', () => { + resolve() + }) + }) + + setTimeout(() => { + if (mapType === MapToggleEnum.RealTimeMode) { + startRotation() + } + isUpdatingPositionRef.current = false + }, 500) + } catch (error) { + console.error('Error updating map position:', error) isUpdatingPositionRef.current = false - }, 500) - } catch (error) { - console.error('Error updating map position:', error) - isUpdatingPositionRef.current = false + } } - } - }, [mapType, startRotation, stopRotation]) + }, + [mapType, startRotation, stopRotation] + ) // Set up drawing tools const setupDrawingTools = useCallback(() => { @@ -462,7 +483,7 @@ export const Mapbox: React.FC<{ position?: { latitude: number; longitude: number return () => { if (map.current) { map.current.off('moveend', captureMapCenter) - + if (drawRef.current) { try { map.current.off('draw.create', updateMeasurementLabels) @@ -473,14 +494,20 @@ export const Mapbox: React.FC<{ position?: { latitude: number; longitude: number console.log('Draw control already removed') } } - - // Clean up any existing labels - Object.values(polygonLabelsRef.current).forEach(marker => marker.remove()) + + if (userMarkerRef.current) { + userMarkerRef.current.remove() + userMarkerRef.current = null + } + + Object.values(polygonLabelsRef.current).forEach(marker => + marker.remove() + ) Object.values(lineLabelsRef.current).forEach(marker => marker.remove()) - + stopRotation() - setIsMapLoaded(false) // Reset map loaded state on cleanup - setMap(null) // Clear map instance from context + setIsMapLoaded(false) + setMap(null) map.current.remove() map.current = null } @@ -579,7 +606,14 @@ export const Mapbox: React.FC<{ position?: { latitude: number; longitude: number } } - Object.values(polygonLabelsRef.current).forEach(marker => marker.remove()) + if (userMarkerRef.current) { + userMarkerRef.current.remove() + userMarkerRef.current = null + } + + Object.values(polygonLabelsRef.current).forEach(marker => + marker.remove() + ) Object.values(lineLabelsRef.current).forEach(marker => marker.remove()) stopRotation() diff --git a/components/map/user-marker.tsx b/components/map/user-marker.tsx new file mode 100644 index 00000000..43c98263 --- /dev/null +++ b/components/map/user-marker.tsx @@ -0,0 +1,29 @@ +'use client' + +import React from 'react' +import Image from 'next/image' + +const UserMarker: React.FC = () => { + return ( +
+ User Location +
+ ) +} + +export default UserMarker