mowing history
This commit is contained in:
@@ -368,6 +368,19 @@ const History = () => {
|
||||
return items;
|
||||
})();
|
||||
|
||||
// Coverage calculation for mowing when shown in unified list
|
||||
const calculateMowingCoverage = (log) => {
|
||||
const meters = (log.total_distance_meters || log.gpsTrack?.totalDistance || log.gps_track?.totalDistance || 0) || 0;
|
||||
const totalDistanceFeet = meters * 3.28084;
|
||||
const plannedArea = Number(log.total_area || 0);
|
||||
if (totalDistanceFeet === 0 || plannedArea === 0) return 0;
|
||||
let equipmentWidth = 6; // default mower deck width in ft
|
||||
const name = (log.equipment_name || '').toLowerCase();
|
||||
if (name.includes('30"') || name.includes('30 in')) equipmentWidth = 2.5;
|
||||
const theoreticalCoverageArea = totalDistanceFeet * equipmentWidth;
|
||||
return Math.min(100, Math.round((theoreticalCoverageArea / plannedArea) * 100));
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="p-6">
|
||||
@@ -655,9 +668,12 @@ const History = () => {
|
||||
<div className="flex justify-between items-start">
|
||||
<div className="flex-1">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h3 className="text-lg font-semibold text-gray-900">
|
||||
{application.propertyName} - {application.sectionNames}
|
||||
</h3>
|
||||
<div className="flex items-center gap-2">
|
||||
<h3 className="text-lg font-semibold text-gray-900">
|
||||
{application.propertyName} - {application.sectionNames}
|
||||
</h3>
|
||||
<span className="px-2 py-0.5 text-xs rounded-full bg-indigo-100 text-indigo-800">Application</span>
|
||||
</div>
|
||||
<span className={`px-3 py-1 text-sm font-medium rounded-full ${
|
||||
application.status === 'archived'
|
||||
? 'bg-gray-100 text-gray-800'
|
||||
@@ -755,23 +771,66 @@ const History = () => {
|
||||
|
||||
// Mowing entry
|
||||
const log = item.log;
|
||||
const durationMin = Math.round((log.duration_seconds || log.durationSeconds || log.gpsTrack?.duration || 0) / 60);
|
||||
const durationMin = Math.round((log.duration_seconds || log.durationSeconds || log.gpsTrack?.duration || log.gps_track?.duration || 0) / 60);
|
||||
const avg = (log.average_speed_mph || log.averageSpeed || 0).toFixed?.(1) || Number(log.averageSpeed || 0).toFixed(1);
|
||||
const distFeet = Math.round(((log.total_distance_meters || log.gpsTrack?.totalDistance || 0) * 3.28084) || 0);
|
||||
const distFeet = Math.round(((log.total_distance_meters || log.gpsTrack?.totalDistance || log.gps_track?.totalDistance || 0) * 3.28084) || 0);
|
||||
return (
|
||||
<div key={`mow-${log.id}`} className="bg-white p-6 rounded-lg shadow hover:shadow-lg transition-shadow">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<div className="font-medium text-gray-900">{log.property_name || 'Property'}</div>
|
||||
<div className="text-sm text-gray-600">{new Date(item.date).toLocaleString()} • {log.equipment_name || 'Mower'} • {avg} mph • {distFeet} ft • {durationMin} min</div>
|
||||
<div className="flex justify-between items-start">
|
||||
<div className="flex-1">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<h3 className="text-lg font-semibold text-gray-900">
|
||||
{(log.property_name || 'Property')} - {(log.section_names || 'Areas')}
|
||||
</h3>
|
||||
<span className="px-2 py-0.5 text-xs rounded-full bg-green-100 text-green-800">Mowing</span>
|
||||
</div>
|
||||
<span className="px-3 py-1 text-sm font-medium rounded-full bg-green-100 text-green-800">Completed</span>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
|
||||
<div className="flex items-center text-sm text-gray-600">
|
||||
<CalendarIcon className="h-4 w-4 mr-2" />
|
||||
{new Date(item.date).toLocaleString()}
|
||||
</div>
|
||||
<div className="flex items-center text-sm text-gray-600">
|
||||
<MapPinIcon className="h-4 w-4 mr-2" />
|
||||
{log.property_name}
|
||||
</div>
|
||||
<div className="flex items-center text-sm text-gray-600">
|
||||
<WrenchScrewdriverIcon className="h-4 w-4 mr-2" />
|
||||
{log.equipment_name || 'Mower'}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-2 mb-4">
|
||||
<div className="bg-blue-50 p-2 rounded text-center">
|
||||
<div className="text-xs text-blue-600 font-medium">Duration</div>
|
||||
<div className="text-sm font-bold text-blue-900">{durationMin} min</div>
|
||||
</div>
|
||||
<div className="bg-green-50 p-2 rounded text-center">
|
||||
<div className="text-xs text-green-600 font-medium">GPS Points</div>
|
||||
<div className="text-sm font-bold text-green-900">{log.gpsTrack?.points?.length || log.gps_track?.points?.length || 0}</div>
|
||||
</div>
|
||||
<div className="bg-purple-50 p-2 rounded text-center">
|
||||
<div className="text-xs text-purple-600 font-medium">Distance</div>
|
||||
<div className="text-sm font-bold text-purple-900">{distFeet} ft</div>
|
||||
</div>
|
||||
<div className="bg-orange-50 p-2 rounded text-center">
|
||||
<div className="text-xs text-orange-600 font-medium">Coverage</div>
|
||||
<div className="text-sm font-bold text-orange-900">{calculateMowingCoverage(log)}%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="ml-4">
|
||||
<button
|
||||
onClick={() => setViewingMowingSession(log)}
|
||||
className="p-2 text-indigo-600 hover:text-indigo-800 hover:bg-indigo-50 rounded"
|
||||
title="View mowing session"
|
||||
>
|
||||
<EyeIcon className="h-5 w-5" />
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setViewingMowingSession(log)}
|
||||
className="p-2 text-indigo-600 hover:text-indigo-800 hover:bg-indigo-50 rounded"
|
||||
title="View mowing session"
|
||||
>
|
||||
<EyeIcon className="h-5 w-5" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user