diff --git a/frontend/src/pages/Properties/PropertyDetail.js b/frontend/src/pages/Properties/PropertyDetail.js index 731d7c8..e92a604 100644 --- a/frontend/src/pages/Properties/PropertyDetail.js +++ b/frontend/src/pages/Properties/PropertyDetail.js @@ -263,7 +263,20 @@ const PropertyDetail = () => { setLoading(true); const response = await propertiesAPI.getById(id); console.log('Property details:', response); - setProperty(response.data.data.property); + const propertyData = response.data.data.property; + setProperty(propertyData); + + // Convert backend sections to frontend format + if (propertyData.sections && propertyData.sections.length > 0) { + const convertedSections = propertyData.sections.map(section => ({ + id: section.id, + name: section.name, + coordinates: section.polygonData?.coordinates?.[0] || [], + color: section.polygonData?.color || SECTION_COLORS[0], + area: section.area + })); + setLawnSections(convertedSections); + } } catch (error) { console.error('Failed to fetch property:', error); toast.error('Failed to load property'); @@ -287,35 +300,61 @@ const PropertyDetail = () => { setIsDrawing(false); }; - const saveLawnSection = () => { + const saveLawnSection = async () => { if (!sectionName.trim()) { toast.error('Please enter a section name'); return; } - const newSection = { - id: Date.now(), - name: sectionName, - coordinates: pendingSection.coordinates, - color: pendingSection.color, - area: pendingSection.area - }; + try { + const sectionData = { + name: sectionName, + area: pendingSection.area, + polygonData: { + coordinates: [pendingSection.coordinates], + color: pendingSection.color + }, + grassType: null, + soilType: null + }; - setLawnSections(prev => [...prev, newSection]); - toast.success(`${sectionName} section created!`); - - // Reset and cycle color - setSectionName(''); - setPendingSection(null); - setShowNameModal(false); - const nextIndex = (SECTION_COLORS.findIndex(c => c.value === currentColor.value) + 1) % SECTION_COLORS.length; - setCurrentColor(SECTION_COLORS[nextIndex]); + const response = await propertiesAPI.createSection(id, sectionData); + const savedSection = response.data.data.section; + + // Convert backend format to frontend format + const newSection = { + id: savedSection.id, + name: savedSection.name, + coordinates: savedSection.polygonData.coordinates[0], + color: savedSection.polygonData.color, + area: savedSection.area + }; + + setLawnSections(prev => [...prev, newSection]); + toast.success(`${sectionName} section created and saved!`); + + // Reset and cycle color + setSectionName(''); + setPendingSection(null); + setShowNameModal(false); + const nextIndex = (SECTION_COLORS.findIndex(c => c.value === currentColor.value) + 1) % SECTION_COLORS.length; + setCurrentColor(SECTION_COLORS[nextIndex]); + } catch (error) { + console.error('Failed to save section:', error); + toast.error('Failed to save section. Please try again.'); + } }; - const deleteLawnSection = (sectionId) => { + const deleteLawnSection = async (sectionId) => { if (window.confirm('Delete this lawn section?')) { - setLawnSections(prev => prev.filter(s => s.id !== sectionId)); - toast.success('Section deleted'); + try { + await propertiesAPI.deleteSection(id, sectionId); + setLawnSections(prev => prev.filter(s => s.id !== sectionId)); + toast.success('Section deleted'); + } catch (error) { + console.error('Failed to delete section:', error); + toast.error('Failed to delete section. Please try again.'); + } } }; @@ -326,29 +365,64 @@ const PropertyDetail = () => { setShowEditModal(true); }; - const saveEditedSection = () => { + const saveEditedSection = async () => { if (!sectionName.trim()) { toast.error('Please enter a section name'); return; } - const updatedSection = { - ...editingSection, - name: sectionName, - color: currentColor - }; + try { + const sectionData = { + name: sectionName, + area: editingSection.area, + polygonData: { + coordinates: [editingSection.coordinates], + color: currentColor + }, + grassType: null, + soilType: null + }; - setLawnSections(prev => prev.map(s => s.id === editingSection.id ? updatedSection : s)); - toast.success('Section updated!'); - - // Reset - setSectionName(''); - setEditingSection(null); - setShowEditModal(false); + await propertiesAPI.updateSection(id, editingSection.id, sectionData); + + const updatedSection = { + ...editingSection, + name: sectionName, + color: currentColor + }; + + setLawnSections(prev => prev.map(s => s.id === editingSection.id ? updatedSection : s)); + toast.success('Section updated and saved!'); + + // Reset + setSectionName(''); + setEditingSection(null); + setShowEditModal(false); + } catch (error) { + console.error('Failed to update section:', error); + toast.error('Failed to update section. Please try again.'); + } }; - const updateSection = (sectionId, updatedSection) => { - setLawnSections(prev => prev.map(s => s.id === sectionId ? updatedSection : s)); + const updateSection = async (sectionId, updatedSection) => { + try { + const sectionData = { + name: updatedSection.name, + area: updatedSection.area, + polygonData: { + coordinates: [updatedSection.coordinates], + color: updatedSection.color + }, + grassType: null, + soilType: null + }; + + await propertiesAPI.updateSection(id, sectionId, sectionData); + setLawnSections(prev => prev.map(s => s.id === sectionId ? updatedSection : s)); + } catch (error) { + console.error('Failed to update section coordinates:', error); + toast.error('Failed to save polygon changes. Please try again.'); + } }; const getTotalArea = () => {