Procházet zdrojové kódy

fix: reactive user location marker, orange (#FF4907) color when logged in

neyrogovnarik před 1 měsícem
rodič
revize
90108e2c4a
2 změnil soubory, kde provedl 28 přidání a 9 odebrání
  1. 20 2
      frontend/src/components/MapView.tsx
  2. 8 7
      frontend/src/lib/map.ts

+ 20 - 2
frontend/src/components/MapView.tsx

@@ -20,6 +20,7 @@ export default function MapView() {
   const [places, setPlaces] = useState<Place[]>([])
   const [selectedPlace, setSelectedPlace] = useState<Place | null>(null)
   const [mapError, setMapError] = useState(false)
+  const userPosRef = useRef<{ lat: number; lng: number } | null>(null)
 
   const fetchPlaces = useCallback(async (bounds?: MapBounds) => {
     try {
@@ -55,10 +56,14 @@ export default function MapView() {
       if (navigator.geolocation) {
         navigator.geolocation.getCurrentPosition(
           (pos) => {
-            provider.setCenter(pos.coords.latitude, pos.coords.longitude)
-            provider.addMarker('_user_location', pos.coords.latitude, pos.coords.longitude, {
+            const lat = pos.coords.latitude
+            const lng = pos.coords.longitude
+            userPosRef.current = { lat, lng }
+            provider.setCenter(lat, lng)
+            provider.addMarker('_user_location', lat, lng, {
               type: 'location',
               ghost: !user,
+              color: user ? '#FF4907' : undefined,
             })
           },
           () => {},
@@ -81,6 +86,19 @@ export default function MapView() {
     }
   }, [])
 
+  useEffect(() => {
+    const pos = userPosRef.current
+    const provider = mapRef.current
+    if (!pos || !provider || !provider.isReady()) return
+
+    provider.removeMarker('_user_location')
+    provider.addMarker('_user_location', pos.lat, pos.lng, {
+      type: 'location',
+      ghost: !user,
+      color: user ? '#FF4907' : undefined,
+    })
+  }, [user])
+
   useEffect(() => {
     const provider = mapRef.current
     if (!provider || !provider.isReady()) return

+ 8 - 7
frontend/src/lib/map.ts

@@ -15,6 +15,7 @@ export interface MarkerOptions {
   title?: string
   onClick?: () => void
   ghost?: boolean
+  color?: string
 }
 
 const TILE_URL = 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png'
@@ -26,15 +27,15 @@ const MARKER_COLORS: Record<string, string> = {
   location: '#3b82f6',
 }
 
-function createIcon(type: string, size: number, ghost?: boolean): L.DivIcon {
-  const color = ghost
+function createIcon(type: string, size: number, ghost?: boolean, color?: string): L.DivIcon {
+  const bg = color || (ghost
     ? 'radial-gradient(circle, rgba(255, 238, 0, 1) 0%, rgba(255, 238, 0, 0) 75%)'
-    : MARKER_COLORS[type] || '#3b82f6'
+    : MARKER_COLORS[type] || '#3b82f6')
 
   if (type === 'location') {
     const locStyle = ghost
       ? `width:10px;height:10px;background:radial-gradient(circle, rgba(255, 238, 0, 1) 0%, rgba(255, 238, 0, 0) 75%);border-radius:50%`
-      : `width:12px;height:12px;background:#3b82f6;border-radius:50%;border:3px solid white;box-shadow:0 0 0 4px rgba(59,130,246,0.3)`
+      : `width:12px;height:12px;background:${bg};border-radius:50%;border:3px solid white;box-shadow:0 0 0 4px rgba(59,130,246,0.3)`
     const s = ghost ? 10 : 20
     return L.divIcon({
       className: '',
@@ -46,8 +47,8 @@ function createIcon(type: string, size: number, ghost?: boolean): L.DivIcon {
 
   const ghostSize = 10
   const style = ghost
-    ? `width:${ghostSize}px;height:${ghostSize}px;background:${color};border-radius:50%`
-    : `width:${size}px;height:${size}px;background:${color};border-radius:50%;border:${size > 20 ? '3px' : '2px'} solid white;box-shadow:0 2px 8px rgba(0,0,0,0.3)`
+    ? `width:${ghostSize}px;height:${ghostSize}px;background:${bg};border-radius:50%`
+    : `width:${size}px;height:${size}px;background:${bg};border-radius:50%;border:${size > 20 ? '3px' : '2px'} solid white;box-shadow:0 2px 8px rgba(0,0,0,0.3)`
 
   return L.divIcon({
     className: '',
@@ -122,7 +123,7 @@ export function createLeafletMapProvider(): MapProvider {
       const ghost = options?.ghost
       const type = options?.type || 'place'
       const size = type === 'visitor' || type === 'visitor_registered' || type === 'location' ? 12 : 32
-      const icon = createIcon(type, size, ghost)
+      const icon = createIcon(type, size, ghost, options?.color)
       const interactive = !ghost
       const marker = L.marker([lat, lng], { icon, interactive }).addTo(map)