polygons
This commit is contained in:
@@ -354,6 +354,8 @@ const PropertyDetail = () => {
|
|||||||
const [gpsAccuracy, setGpsAccuracy] = useState(null);
|
const [gpsAccuracy, setGpsAccuracy] = useState(null);
|
||||||
const [isSnapPreview, setIsSnapPreview] = useState(false);
|
const [isSnapPreview, setIsSnapPreview] = useState(false);
|
||||||
const [showAddMenu, setShowAddMenu] = useState(false);
|
const [showAddMenu, setShowAddMenu] = useState(false);
|
||||||
|
// Modal picker to ensure options show reliably on mobile
|
||||||
|
const [showCaptureModeModal, setShowCaptureModeModal] = useState(false);
|
||||||
const [currentColor, setCurrentColor] = useState(SECTION_COLORS[0]);
|
const [currentColor, setCurrentColor] = useState(SECTION_COLORS[0]);
|
||||||
const [showNameModal, setShowNameModal] = useState(false);
|
const [showNameModal, setShowNameModal] = useState(false);
|
||||||
const [pendingSection, setPendingSection] = useState(null);
|
const [pendingSection, setPendingSection] = useState(null);
|
||||||
@@ -813,49 +815,14 @@ const PropertyDetail = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<button
|
<button
|
||||||
onClick={() => setShowAddMenu(v=>!v)}
|
onClick={() => setShowCaptureModeModal(true)}
|
||||||
className="btn-primary flex items-center gap-2"
|
className="btn-primary flex items-center gap-2"
|
||||||
title="Add a lawn section"
|
title="Add a lawn section"
|
||||||
>
|
>
|
||||||
<PlusIcon className="h-5 w-5" />
|
<PlusIcon className="h-5 w-5" />
|
||||||
Add Lawn Section
|
Add Lawn Section
|
||||||
</button>
|
</button>
|
||||||
{showAddMenu && (
|
{/* Dropdown removed in favor of modal for reliability */}
|
||||||
<div className="absolute right-0 mt-2 w-56 bg-white border rounded shadow-lg z-10">
|
|
||||||
<button
|
|
||||||
className="w-full text-left px-3 py-2 hover:bg-gray-50"
|
|
||||||
onClick={() => { setShowAddMenu(false); setIsDrawing(true); setIsGPSPointsMode(false); setIsGPSTraceMode(false); }}
|
|
||||||
>
|
|
||||||
Tap to Draw (manual)
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className="w-full text-left px-3 py-2 hover:bg-gray-50"
|
|
||||||
onClick={() => {
|
|
||||||
setShowAddMenu(false);
|
|
||||||
// Enable GPS points mode, disable trace
|
|
||||||
setIsGPSTraceMode(false);
|
|
||||||
setIsTracing(false);
|
|
||||||
if (gpsWatchId) { navigator.geolocation.clearWatch(gpsWatchId); setGpsWatchId(null); }
|
|
||||||
clearGpsPoints();
|
|
||||||
setIsGPSPointsMode(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
GPS Points (walk and mark)
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className="w-full text-left px-3 py-2 hover:bg-gray-50"
|
|
||||||
onClick={() => {
|
|
||||||
setShowAddMenu(false);
|
|
||||||
// Enable trace mode, disable points mode
|
|
||||||
setIsGPSPointsMode(false);
|
|
||||||
clearGpsPoints();
|
|
||||||
setIsGPSTraceMode(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Trace Boundary (continuous)
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -1097,6 +1064,58 @@ const PropertyDetail = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Capture Mode Modal */}
|
||||||
|
{showCaptureModeModal && (
|
||||||
|
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center" style={{ zIndex: 9999 }}>
|
||||||
|
<div className="bg-white rounded-lg p-6 w-96 max-w-[92vw] shadow-2xl">
|
||||||
|
<h3 className="text-lg font-semibold mb-4">Create Lawn Section</h3>
|
||||||
|
<div className="space-y-3">
|
||||||
|
<button
|
||||||
|
className="w-full px-4 py-3 border rounded hover:bg-gray-50 text-left"
|
||||||
|
onClick={() => {
|
||||||
|
setShowCaptureModeModal(false);
|
||||||
|
setIsDrawing(true);
|
||||||
|
setIsGPSPointsMode(false);
|
||||||
|
setIsGPSTraceMode(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="font-medium">Tap to Draw (manual)</div>
|
||||||
|
<div className="text-xs text-gray-600">Tap the map to add corners, double‑tap to finish.</div>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="w-full px-4 py-3 border rounded hover:bg-gray-50 text-left"
|
||||||
|
onClick={() => {
|
||||||
|
setShowCaptureModeModal(false);
|
||||||
|
setIsGPSTraceMode(false);
|
||||||
|
setIsTracing(false);
|
||||||
|
if (gpsWatchId) { navigator.geolocation.clearWatch(gpsWatchId); setGpsWatchId(null); }
|
||||||
|
clearGpsPoints();
|
||||||
|
setIsGPSPointsMode(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="font-medium">GPS Points (walk and mark)</div>
|
||||||
|
<div className="text-xs text-gray-600">Walk to each corner and tap “Mark Point”, then Complete.</div>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="w-full px-4 py-3 border rounded hover:bg-gray-50 text-left"
|
||||||
|
onClick={() => {
|
||||||
|
setShowCaptureModeModal(false);
|
||||||
|
setIsGPSPointsMode(false);
|
||||||
|
clearGpsPoints();
|
||||||
|
setIsGPSTraceMode(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="font-medium">Trace Boundary (continuous)</div>
|
||||||
|
<div className="text-xs text-gray-600">Start tracing and walk the perimeter. Pause as needed, then Complete.</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="mt-4 flex justify-end">
|
||||||
|
<button className="btn-secondary" onClick={() => setShowCaptureModeModal(false)}>Cancel</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Recent History */}
|
{/* Recent History */}
|
||||||
<div className="mt-8">
|
<div className="mt-8">
|
||||||
<h2 className="text-lg font-semibold mb-3">Recent History</h2>
|
<h2 className="text-lg font-semibold mb-3">Recent History</h2>
|
||||||
|
|||||||
Reference in New Issue
Block a user