This commit is contained in:
Jake Kasper
2025-09-05 11:17:37 -04:00
parent c517b28f51
commit 12a74b4828

View File

@@ -586,25 +586,25 @@ const Watering = () => {
<div className="lg:col-span-3">
<div className="card p-0" style={{height:'70vh', position:'relative'}}>
<div className="flex items-center justify-between p-3 border-b">
<div className="text-sm text-gray-700">{guiding && currentPos && points[guideIndex] ? (()=>{
const tgt = {lat:Number(points[guideIndex].lat), lng:Number(points[guideIndex].lng)};
<div className="text-sm text-gray-700">{guiding && currentPos && sortedPoints[guideIndex] ? (()=>{
const tgt = {lat:Number(sortedPoints[guideIndex].lat), lng:Number(sortedPoints[guideIndex].lng)};
const dist = distanceFeet(currentPos, tgt);
const brg = bearingDegrees(currentPos, tgt);
if (dist <= 15) {
return <span className="text-green-700 font-semibold">Arrived at #{points[guideIndex].sequence} {dist.toFixed(0)} ft</span>;
return <span className="text-green-700 font-semibold">Arrived at #{guideIndex+1} {dist.toFixed(0)} ft</span>;
}
return <> {brg}° {dist.toFixed(0)} ft Point #{points[guideIndex].sequence}</>;
return <> {brg}° {dist.toFixed(0)} ft Point #{guideIndex+1}</>;
})() : 'Map'}</div>
<div className="flex gap-2 items-center">
<label className="text-xs flex items-center gap-1">
<input type="checkbox" checked={satellite} onChange={(e)=> setSatellite(e.target.checked)} /> Satellite
</label>
{!guiding ? (
<button className="btn-secondary" onClick={startGuidance} disabled={points.length===0}>Start Guidance</button>
<button className="btn-secondary" onClick={startGuidance} disabled={sortedPoints.length===0}>Start Guidance</button>
) : (
<>
<button className="btn-secondary" onClick={()=> setGuideIndex(i=> Math.max(0, i-1))} disabled={guideIndex===0}>Prev</button>
<button className="btn-secondary" onClick={()=> setGuideIndex(i=> Math.min(points.length-1, i+1))} disabled={guideIndex>=points.length-1}>Next</button>
<button className="btn-secondary" onClick={()=> setGuideIndex(i=> Math.min(sortedPoints.length-1, i+1))} disabled={guideIndex>=sortedPoints.length-1}>Next</button>
<button className="btn-primary" onClick={stopGuidance}>Stop</button>
</>
)}
@@ -621,26 +621,26 @@ const Watering = () => {
<Polygon key={s.id} positions={s.polygonData?.coordinates?.[0]||[]} pathOptions={{ color:'#16a34a', weight:2, fillOpacity:0.1 }} />
))}
{placing && <SprinklerPlacement onPlace={onPlace} />}
{guiding && currentPos && points[guideIndex] && (
{guiding && currentPos && sortedPoints[guideIndex] && (
<>
{/* Current location marker */}
<Marker position={[currentPos.lat, currentPos.lng]} icon={markerIcon('#0ea5e9')} />
{/* Line to target */}
<Polyline positions={[[currentPos.lat, currentPos.lng], [Number(points[guideIndex].lat), Number(points[guideIndex].lng)]]} pathOptions={{ color:'#0ea5e9', dashArray:'6 6' }} />
<Polyline positions={[[currentPos.lat, currentPos.lng], [Number(sortedPoints[guideIndex].lat), Number(sortedPoints[guideIndex].lng)]]} pathOptions={{ color:'#0ea5e9', dashArray:'6 6' }} />
{/* Arrival ring */}
<Circle center={[Number(points[guideIndex].lat), Number(points[guideIndex].lng)]} radius={15*0.3048} pathOptions={{ color:'#22c55e', fillOpacity:0.15, weight:2 }} />
<Circle center={[Number(sortedPoints[guideIndex].lat), Number(sortedPoints[guideIndex].lng)]} radius={15*0.3048} pathOptions={{ color:'#22c55e', fillOpacity:0.15, weight:2 }} />
</>
)}
{/* Legend overlay */}
{points.length > 0 && (
{sortedPoints.length > 0 && (
<div style={{ position:'absolute', right:10, bottom:10, zIndex:1000 }}>
<div className="bg-white/90 border rounded shadow p-2 max-h-56 overflow-auto text-xs">
<div className="font-medium mb-1">Legend</div>
<ul className="space-y-1">
{points.map(pt => (
{sortedPoints.map((pt, idx) => (
<li key={`lg-${pt.id}`} className="flex items-center gap-2">
<span style={{backgroundColor: pointColor(pt)}} className="inline-block w-3 h-3 rounded-full"></span>
<span className="font-mono">#{pt.sequence}</span>
<span className="font-mono">#{idx+1}</span>
<span className="text-gray-700">{pt.equipment_name || (pt.sprinkler_head_type||'-').replace('_',' ')}</span>
{pt.sprinkler_gpm ? (<span className="text-gray-600"> {Number(pt.sprinkler_gpm)} gpm</span>) : null}
{pt.duration_minutes ? (<span className="text-gray-600"> {pt.duration_minutes} min</span>) : null}
@@ -650,7 +650,7 @@ const Watering = () => {
</div>
</div>
)}
{points.map(pt => {
{sortedPoints.map(pt => {
const cov = computeCoverage({
type: pt.sprinkler_head_type,
throwFeet: parseFloat(pt.sprinkler_throw_feet||0),