update some stuff

This commit is contained in:
Jake Kasper
2025-08-21 17:46:56 -04:00
parent b114fb1d22
commit 79bff678f7

View File

@@ -8,7 +8,8 @@ import {
TrashIcon,
ArrowLeftIcon,
MapPinIcon,
SwatchIcon
SwatchIcon,
PencilIcon
} from '@heroicons/react/24/outline';
import { propertiesAPI } from '../../services/api';
import LoadingSpinner from '../../components/UI/LoadingSpinner';
@@ -54,10 +55,19 @@ function PolygonDrawer({ isDrawing, onPolygonComplete, currentColor }) {
if (!isDrawing) return;
const newPoint = [e.latlng.lat, e.latlng.lng];
setCurrentPolygon(prev => [...prev, newPoint]);
console.log('Adding point:', newPoint);
setCurrentPolygon(prev => {
const newPoly = [...prev, newPoint];
console.log('Current polygon has', newPoly.length, 'points');
return newPoly;
});
},
dblclick() {
dblclick(e) {
console.log('Double click detected, drawing:', isDrawing, 'points:', currentPolygon.length);
if (isDrawing && currentPolygon.length >= 3) {
e.originalEvent.preventDefault();
e.originalEvent.stopPropagation();
console.log('Completing polygon with', currentPolygon.length, 'points');
onPolygonComplete(currentPolygon);
setCurrentPolygon([]);
}
@@ -89,11 +99,30 @@ const PropertyDetail = () => {
const [showNameModal, setShowNameModal] = useState(false);
const [pendingSection, setPendingSection] = useState(null);
const [sectionName, setSectionName] = useState('');
const [editingSection, setEditingSection] = useState(null);
const [showEditModal, setShowEditModal] = useState(false);
useEffect(() => {
fetchPropertyDetails();
}, [id]); // eslint-disable-line react-hooks/exhaustive-deps
// Handle keyboard shortcuts for polygon drawing
useEffect(() => {
const handleKeyPress = (e) => {
if (isDrawing && e.key === 'Enter') {
// Find the PolygonDrawer component and complete the polygon
console.log('Enter pressed during drawing mode');
}
if (e.key === 'Escape' && isDrawing) {
setIsDrawing(false);
toast.info('Drawing cancelled');
}
};
document.addEventListener('keydown', handleKeyPress);
return () => document.removeEventListener('keydown', handleKeyPress);
}, [isDrawing]);
const fetchPropertyDetails = async () => {
try {
setLoading(true);
@@ -110,12 +139,14 @@ const PropertyDetail = () => {
};
const handlePolygonComplete = (coordinates) => {
console.log('handlePolygonComplete called with', coordinates.length, 'coordinates');
if (coordinates.length < 3) {
toast.error('Polygon needs at least 3 points');
return;
}
const area = calculateAreaInSqFt([...coordinates, coordinates[0]]);
console.log('Calculated area:', area);
setPendingSection({ coordinates, color: currentColor, area });
setShowNameModal(true);
setIsDrawing(false);
@@ -153,6 +184,34 @@ const PropertyDetail = () => {
}
};
const startEditSection = (section) => {
setEditingSection(section);
setSectionName(section.name);
setCurrentColor(section.color);
setShowEditModal(true);
};
const saveEditedSection = () => {
if (!sectionName.trim()) {
toast.error('Please enter a section name');
return;
}
const updatedSection = {
...editingSection,
name: sectionName,
color: currentColor
};
setLawnSections(prev => prev.map(s => s.id === editingSection.id ? updatedSection : s));
toast.success('Section updated!');
// Reset
setSectionName('');
setEditingSection(null);
setShowEditModal(false);
};
const getTotalArea = () => {
return lawnSections.reduce((total, section) => total + section.area, 0);
};
@@ -231,7 +290,8 @@ const PropertyDetail = () => {
<div style={{ height: '600px', width: '100%' }}>
<MapContainer
center={mapCenter}
zoom={hasValidCoordinates ? 19 : 13}
zoom={hasValidCoordinates ? 21 : 13}
maxZoom={23}
style={{ height: '100%', width: '100%' }}
>
<TileLayer
@@ -260,13 +320,21 @@ const PropertyDetail = () => {
<div className="text-center">
<strong>{section.name}</strong><br />
{section.area.toLocaleString()} sq ft<br />
<div className="flex gap-2 mt-2">
<button
onClick={() => startEditSection(section)}
className="text-blue-600 text-sm"
>
Edit
</button>
<button
onClick={() => deleteLawnSection(section.id)}
className="text-red-600 text-sm mt-2"
className="text-red-600 text-sm"
>
Delete
</button>
</div>
</div>
</Popup>
</Polygon>
))}
@@ -282,9 +350,15 @@ const PropertyDetail = () => {
</div>
{isDrawing && (
<div className="p-4 bg-blue-50">
<div className="p-4 bg-blue-50 border-t">
<div className="flex items-center gap-2">
<div className="w-3 h-3 bg-blue-600 rounded-full animate-pulse"></div>
<p className="text-sm text-blue-800">
<strong>Drawing Mode:</strong> Click to add points. Double-click to complete polygon.
<strong>Drawing Mode Active:</strong> Click to add points. Double-click to complete polygon.
</p>
</div>
<p className="text-xs text-blue-600 mt-1">
Need at least 3 points to create a section. Press ESC to cancel.
</p>
</div>
)}
@@ -350,6 +424,13 @@ const PropertyDetail = () => {
<p className="text-xs text-gray-600">{section.area.toLocaleString()} sq ft</p>
</div>
</div>
<div className="flex gap-1">
<button
onClick={() => startEditSection(section)}
className="text-blue-600 hover:text-blue-800"
>
<PencilIcon className="h-4 w-4" />
</button>
<button
onClick={() => deleteLawnSection(section.id)}
className="text-red-600 hover:text-red-800"
@@ -357,6 +438,7 @@ const PropertyDetail = () => {
<TrashIcon className="h-4 w-4" />
</button>
</div>
</div>
))}
</div>
)}
@@ -366,8 +448,8 @@ const PropertyDetail = () => {
{/* Name Modal */}
{showNameModal && (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div className="bg-white rounded-lg p-6 w-96">
<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 shadow-2xl">
<h3 className="text-lg font-semibold mb-4">Name Your Lawn Section</h3>
<div className="space-y-4">
<input
@@ -404,6 +486,68 @@ const PropertyDetail = () => {
</div>
</div>
)}
{/* Edit Modal */}
{showEditModal && (
<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 shadow-2xl">
<h3 className="text-lg font-semibold mb-4">Edit Lawn Section</h3>
<div className="space-y-4">
<div>
<label className="label">Section Name</label>
<input
type="text"
className="input"
value={sectionName}
onChange={(e) => setSectionName(e.target.value)}
placeholder="e.g., Front Yard, Back Lawn"
autoFocus
/>
</div>
<div>
<label className="label">Color</label>
<div className="grid grid-cols-3 gap-2">
{SECTION_COLORS.map((color) => (
<button
key={color.value}
onClick={() => setCurrentColor(color)}
className={`w-10 h-10 rounded border-2 ${
currentColor.value === color.value ? 'border-gray-900' : 'border-gray-300'
}`}
style={{ backgroundColor: color.value }}
title={color.name}
/>
))}
</div>
</div>
<div className="flex items-center gap-2 text-sm text-gray-600">
<div
className="w-4 h-4 rounded"
style={{ backgroundColor: currentColor.value }}
/>
<span>{editingSection?.area.toLocaleString()} sq ft</span>
</div>
</div>
<div className="flex gap-3 mt-6">
<button onClick={saveEditedSection} className="btn-primary flex-1">
Save Changes
</button>
<button
onClick={() => {
setShowEditModal(false);
setEditingSection(null);
setSectionName('');
}}
className="btn-secondary flex-1"
>
Cancel
</button>
</div>
</div>
</div>
)}
</div>
);
};