mowing execution

This commit is contained in:
Jake Kasper
2025-09-02 12:23:40 -05:00
parent 45a9743775
commit cdadedec3f

View File

@@ -9,6 +9,10 @@ const MowingExecutionModal = ({ plan, onClose, onComplete }) => {
const [tracking, setTracking] = useState(false); const [tracking, setTracking] = useState(false);
const [isPaused, setIsPaused] = useState(false); const [isPaused, setIsPaused] = useState(false);
const [gpsTrack, setGpsTrack] = useState([]); const [gpsTrack, setGpsTrack] = useState([]);
const [currentLocation, setCurrentLocation] = useState(null);
const [currentSpeed, setCurrentSpeed] = useState(0);
const [previousLocation, setPreviousLocation] = useState(null);
const [previousTime, setPreviousTime] = useState(null);
const [startTime, setStartTime] = useState(null); const [startTime, setStartTime] = useState(null);
const [totalDistance, setTotalDistance] = useState(0); const [totalDistance, setTotalDistance] = useState(0);
const totalDistanceRef = useRef(0); const totalDistanceRef = useRef(0);
@@ -41,17 +45,26 @@ const MowingExecutionModal = ({ plan, onClose, onComplete }) => {
requestWakeLock(); requestWakeLock();
setTracking(true); setIsPaused(false); setTracking(true); setIsPaused(false);
if (!startTime) setStartTime(new Date()); if (!startTime) setStartTime(new Date());
setPreviousLocation(null); setPreviousTime(null);
const id = navigator.geolocation.watchPosition((pos) => { const id = navigator.geolocation.watchPosition((pos) => {
const { latitude, longitude, speed } = pos.coords; const { latitude, longitude, accuracy, speed } = pos.coords;
const pt = { lat: latitude, lng: longitude, timestamp: new Date(pos.timestamp).toISOString(), speed: speed || 0 }; const timestamp = new Date(pos.timestamp);
setGpsTrack(prev => { const pt = { lat: latitude, lng: longitude, accuracy, timestamp: timestamp.toISOString(), speed: speed || 0 };
if (prev.length > 0) { setCurrentLocation({ lat: latitude, lng: longitude, accuracy });
const meters = haversineMeters(prev[prev.length-1], pt); // Calculate speed/distance similar to Applications execution
if (previousLocation && previousTime) {
const meters = haversineMeters(previousLocation, pt);
const dt = (timestamp - previousTime) / 1000; // seconds
if (dt > 0) {
const mph = (meters / dt) * 2.237;
setCurrentSpeed(mph);
const newTotal = totalDistanceRef.current + meters; totalDistanceRef.current = newTotal; setTotalDistance(newTotal); const newTotal = totalDistanceRef.current + meters; totalDistanceRef.current = newTotal; setTotalDistance(newTotal);
const seconds = startTime ? ((new Date(pos.timestamp)-startTime)/1000) : 0; if (seconds>0) setAverageSpeed((newTotal/seconds)*2.237); const elapsed = startTime ? ((timestamp - startTime) / 1000) : 0; if (elapsed > 0) setAverageSpeed((newTotal / elapsed) * 2.237);
} }
return [...prev, pt]; }
}); setPreviousLocation({ lat: latitude, lng: longitude });
setPreviousTime(timestamp);
setGpsTrack(prev => [...prev, pt]);
}, (err)=> toast.error('GPS error: '+err.message), { enableHighAccuracy: true, timeout: 5000, maximumAge: 1000 }); }, (err)=> toast.error('GPS error: '+err.message), { enableHighAccuracy: true, timeout: 5000, maximumAge: 1000 });
setWatchId(id); setWatchId(id);
}; };
@@ -114,7 +127,17 @@ const MowingExecutionModal = ({ plan, onClose, onComplete }) => {
<div><span className="font-medium">Cut Height:</span> {plan.cut_height_inches}"</div> <div><span className="font-medium">Cut Height:</span> {plan.cut_height_inches}"</div>
</div> </div>
<div className="h-80 border rounded mb-4"> <div className="h-80 border rounded mb-4">
<PropertyMap property={null} sections={sections} selectedSections={sections.map(s=>s.id)} mode="execution" gpsTrack={gpsTrack} currentLocation={null} center={center} zoom={center?16:15} /> <PropertyMap
property={null}
sections={sections}
selectedSections={sections.map(s=>s.id)}
mode="execution"
gpsTrack={gpsTrack}
currentLocation={currentLocation}
center={center || [39.8283, -98.5795]}
zoom={center ? 16 : 15}
className="h-80 w-full"
/>
</div> </div>
<div className="flex gap-3 mb-4"> <div className="flex gap-3 mb-4">
{!tracking ? ( {!tracking ? (
@@ -130,6 +153,7 @@ const MowingExecutionModal = ({ plan, onClose, onComplete }) => {
<div><span className="font-medium">Points:</span> {gpsTrack.length}</div> <div><span className="font-medium">Points:</span> {gpsTrack.length}</div>
<div><span className="font-medium">Distance:</span> {(totalDistance*3.28084).toFixed(0)} ft</div> <div><span className="font-medium">Distance:</span> {(totalDistance*3.28084).toFixed(0)} ft</div>
<div><span className="font-medium">Avg Speed:</span> {averageSpeed.toFixed(1)} mph</div> <div><span className="font-medium">Avg Speed:</span> {averageSpeed.toFixed(1)} mph</div>
<div className="col-span-4 text-xs text-gray-500">Current: {currentSpeed.toFixed(1)} mph {currentLocation?.accuracy ? `${Math.round(currentLocation.accuracy)}m)` : ''}</div>
<div><span className="font-medium">Duration:</span> {startTime ? Math.round((new Date()-startTime)/60000) : 0} min</div> <div><span className="font-medium">Duration:</span> {startTime ? Math.round((new Date()-startTime)/60000) : 0} min</div>
</div> </div>
</div> </div>
@@ -138,4 +162,3 @@ const MowingExecutionModal = ({ plan, onClose, onComplete }) => {
}; };
export default MowingExecutionModal; export default MowingExecutionModal;