perform applications

This commit is contained in:
Jake Kasper
2025-08-27 09:10:43 -04:00
parent abff69cad6
commit a6d3435f1c
3 changed files with 664 additions and 4 deletions

View File

@@ -1,5 +1,5 @@
import React, { useState, useCallback, useRef } from 'react';
import { MapContainer, TileLayer, Polygon, Marker, useMapEvents } from 'react-leaflet';
import { MapContainer, TileLayer, Polygon, Marker, Polyline, useMapEvents } from 'react-leaflet';
import { Icon } from 'leaflet';
import 'leaflet/dist/leaflet.css';
@@ -11,6 +11,28 @@ Icon.Default.mergeOptions({
shadowUrl: require('leaflet/dist/images/marker-shadow.png'),
});
// Custom GPS tracking icons
const currentLocationIcon = new Icon({
iconUrl: 'data:image/svg+xml;base64,' + btoa(`
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<circle cx="10" cy="10" r="8" fill="#3B82F6" stroke="white" stroke-width="2"/>
<circle cx="10" cy="10" r="4" fill="white"/>
</svg>
`),
iconSize: [20, 20],
iconAnchor: [10, 10],
});
const trackPointIcon = new Icon({
iconUrl: 'data:image/svg+xml;base64,' + btoa(`
<svg xmlns="http://www.w3.org/2000/svg" width="6" height="6" viewBox="0 0 6 6">
<circle cx="3" cy="3" r="2" fill="#10B981"/>
</svg>
`),
iconSize: [6, 6],
iconAnchor: [3, 3],
});
// Custom component to handle map clicks for drawing polygons
const DrawingHandler = ({ isDrawing, onPointAdd, onDrawingComplete }) => {
useMapEvents({
@@ -64,7 +86,12 @@ const PropertyMap = ({
onSectionClick,
selectedSections = [],
editable = false,
className = "h-96 w-full"
className = "h-96 w-full",
// GPS tracking props
mode = "view", // "view", "edit", "execution"
gpsTrack = [],
currentLocation = null,
showTrackPoints = true
}) => {
const [isDrawing, setIsDrawing] = useState(false);
const [currentPolygon, setCurrentPolygon] = useState([]);
@@ -390,6 +417,41 @@ const PropertyMap = ({
);
})}
{/* GPS Tracking Elements */}
{mode === "execution" && (
<>
{/* GPS Track Polyline */}
{gpsTrack.length > 1 && (
<Polyline
positions={gpsTrack.map(point => [point.lat, point.lng])}
pathOptions={{
color: '#10B981',
weight: 4,
opacity: 0.8,
}}
/>
)}
{/* Track Points (breadcrumbs) */}
{showTrackPoints && gpsTrack.map((point, index) => (
index % 10 === 0 && ( // Show every 10th point to avoid clutter
<Marker
key={`track-${index}`}
position={[point.lat, point.lng]}
icon={trackPointIcon}
/>
)
))}
{/* Current Location */}
{currentLocation && (
<Marker
position={[currentLocation.lat, currentLocation.lng]}
icon={currentLocationIcon}
/>
)}
</>
)}
{/* Current polygon being drawn */}
{currentPolygon.length > 0 && (
@@ -440,8 +502,25 @@ const PropertyMap = ({
</div>
)}
{/* GPS Tracking stats */}
{mode === "execution" && gpsTrack.length > 0 && (
<div className="absolute bottom-4 left-4 bg-white rounded-lg shadow-lg p-3">
<p className="text-sm font-medium text-gray-700">
GPS Tracking Active
</p>
<p className="text-xs text-gray-600">
Track Points: {gpsTrack.length}
</p>
{currentLocation && (
<p className="text-xs text-gray-600">
Accuracy: ±{Math.round(currentLocation.accuracy || 0)}m
</p>
)}
</div>
)}
{/* Section stats */}
{sections.length > 0 && !isDrawing && (
{sections.length > 0 && !isDrawing && mode !== "execution" && (
<div className="absolute bottom-4 left-4 bg-white rounded-lg shadow-lg p-3">
<p className="text-sm font-medium text-gray-700">
{sections.length} Section{sections.length !== 1 ? 's' : ''}