Add Geofence visualization layer on map
Implemented visual representation of geofences on the main map view: **New Component:** - GeofenceLayer.tsx - Renders active geofences as circles with: - Configurable opacity (15% fill, 80% border) - Color matching from geofence settings - Interactive popups showing zone details (name, device, radius, coordinates) - Auto-refresh every 30 seconds **Map Integration:** - Added toggle button to show/hide geofences (top-right corner) - Purple button when active, white when hidden - Only displays active geofences (is_active = 1) - Geofences render below markers for better visibility **Features:** - Real-time sync with geofence management - Responsive to geofence changes (color, radius, status) - Clean visual hierarchy with location markers on top - Hover/click popups for detailed zone information Users can now visually see their geofence zones on the map and understand the spatial relationship between device locations and zones. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,7 @@ import {
|
||||
LayersControl,
|
||||
useMap,
|
||||
} from "react-leaflet";
|
||||
import GeofenceLayer from "./GeofenceLayer";
|
||||
|
||||
interface MapViewProps {
|
||||
selectedDevice: string;
|
||||
@@ -73,6 +74,7 @@ export default function MapView({ selectedDevice, timeFilter, isPaused, filterMo
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [mapCenter, setMapCenter] = useState<[number, number] | null>(null);
|
||||
const [currentZoom, setCurrentZoom] = useState(12);
|
||||
const [showGeofences, setShowGeofences] = useState(true);
|
||||
const intervalRef = useRef<NodeJS.Timeout | null>(null);
|
||||
|
||||
// Add animation styles for latest marker
|
||||
@@ -226,7 +228,22 @@ export default function MapView({ selectedDevice, timeFilter, isPaused, filterMo
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="h-full w-full">
|
||||
<div className="h-full w-full relative">
|
||||
{/* Geofence Toggle Button */}
|
||||
<div className="absolute top-4 right-4 z-[1000]">
|
||||
<button
|
||||
onClick={() => setShowGeofences(!showGeofences)}
|
||||
className={`px-4 py-2 rounded-lg shadow-lg font-semibold text-sm transition-all ${
|
||||
showGeofences
|
||||
? "bg-purple-600 text-white hover:bg-purple-700"
|
||||
: "bg-white text-gray-700 hover:bg-gray-100"
|
||||
}`}
|
||||
title={showGeofences ? "Hide Geofences" : "Show Geofences"}
|
||||
>
|
||||
📍 {showGeofences ? "Hide" : "Show"} Geofences
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<MapContainer
|
||||
center={[48.1351, 11.582]}
|
||||
zoom={12}
|
||||
@@ -328,6 +345,9 @@ export default function MapView({ selectedDevice, timeFilter, isPaused, filterMo
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
{/* Geofence Layer */}
|
||||
<GeofenceLayer visible={showGeofences} />
|
||||
</MapContainer>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user