import React, { useState, useMemo, useEffect } from 'react'; import { MapContainer, TileLayer, Polygon, useMapEvents, Marker, Popup } from 'react-leaflet'; import { X, Home, DollarSign, User, Info, Edit2, Save, Check, MapPin, Loader2, Plus, AlertCircle } from 'lucide-react'; import 'leaflet/dist/leaflet.css'; import { useMockStore } from '../data/mockStore'; import { useAuth } from '../context/AuthContext'; import { SpotlightCard } from '../components/SpotlightCard'; import { useTheme } from '../context/ThemeContext'; import { logger } from '../utils/logger'; import { toast } from 'sonner'; import Loader from '../components/Loader'; // Fix for default Leaflet marker icons not showing up import L from 'leaflet'; import icon from 'leaflet/dist/images/marker-icon.png'; import iconShadow from 'leaflet/dist/images/marker-shadow.png'; let DefaultIcon = L.icon({ iconUrl: icon, shadowUrl: iconShadow, iconSize: [25, 41], iconAnchor: [12, 41] }); L.Marker.prototype.options.icon = DefaultIcon; // --- COMPONENTS --- const StatusBadge = ({ status }) => { const colors = { "Neutral": "bg-violet-400", "Hot Lead": "bg-red-500", "Renovated": "bg-blue-500", "Customer": "bg-emerald-500", "Not Interested": "bg-black" }; return ( {status} ); }; // Map Interaction Component const MapInteraction = ({ onMapClick }) => { useMapEvents({ click(e) { onMapClick(e.latlng); }, }); return null; }; const MapLegend = () => (

Map Legend

Hot Lead
Customer
Renovated
Neutral
Not Interested
); // Map View const MapView = ({ data, onSelect, onMapCreate }) => { const mapStart = [33.0708, -96.7455]; const { theme } = useTheme(); // Get current theme return ( {/* - Light Mode: Standard vibrant OSM tiles (no filters) - Dark Mode: Inverted, Grayscale, High Contrast for dark map - Key prop forces remount on theme change to ensure tiles update immediately */} {data.map((item) => { let color = "#a78bfa"; // Violet-400 (New Neutral) let fillOpacity = 0.2; switch (item.canvassingStatus) { case "Hot Lead": color = "#ef4444"; // Red-500 fillOpacity = 0.4; break; case "Customer": color = "#10b981"; // Emerald-500 fillOpacity = 0.3; break; case "Renovated": color = "#3b82f6"; // Blue-500 break; case "Not Interested": color = "#18181b"; // Zinc-900 (Blackish) fillOpacity = 0.1; break; default: // Neutral (Violet) break; } return ( { L.DomEvent.stopPropagation(e); // Prevent map click onSelect(item); }, }} /> ); })} ); }; const Drawer = ({ isOpen, onClose, data, newLocation, onUpdateStatus, onSave, loadingAddr }) => { const [isEditing, setIsEditing] = useState(false); // Initial State Matching Schema const initialFormState = { // Status status: 'Neutral', // 1.1 Basic Property Details propertyType: 'House', builtUpArea: '', lotSize: '', yearBuilt: '', bedrooms: '', bathrooms: '', parkingSpaces: '', // 1.2 Transaction & Market purchaseDate: '', purchasePrice: '', marketValue: 0, taxValue: '', // 1.3 Renovation roofCondition: 'Good', lastRenovationDate: '', // 1.4 Rental Status isRented: 'No', // Yes/No tenantName: '', currentRent: '', leaseEnd: '', ownerWillingToRent: 'Yes', expectedRent: '', // 1.5 Location schoolDistrict: '', neighborhoodRating: 5, // 2.1 Owner Details ownerName: '', ownerPhone: '', ownerEmail: '', ownerAddress: '', occupation: '', ownershipType: 'Individual', // 2.4 Owner Intent willingToSell: 'No', desiredPrice: '', minPrice: '', // Notes notes: '' }; const [formData, setFormData] = useState(initialFormState); // Reset or Initialize Form useEffect(() => { if (data) { // Mapping existing data to form state (handling potentially missing fields safely) setFormData({ ...initialFormState, status: data.canvassingStatus || 'Neutral', ownerName: data.ownerData?.fullName || '', ownerPhone: data.ownerData?.primaryPhoneNumber || '', ownerEmail: data.ownerData?.emailAddress || '', marketValue: data.propertyData?.currentEstimatedMarketValue || 0, notes: data.propertyData?.notes || '', propertyType: data.propertyData?.propertyType || 'House', // Correctly map fields from mockStore structure (flat objects) to form state builtUpArea: data.propertyData?.totalBuiltUpArea || '', lotSize: data.propertyData?.lotPlotSize || '', // mockStore might return string "0.22 Acres", assuming input handles text or needs parsing if strictly number yearBuilt: data.propertyData?.yearBuilt || '', bedrooms: data.propertyData?.numberOfBedrooms || '', bathrooms: data.propertyData?.numberOfBathrooms || '', parkingSpaces: data.propertyData?.numberOfParkingSpaces || '', taxValue: data.propertyData?.propertyTaxAssessmentValue || '', roofCondition: data.propertyData?.roofCondition || 'Good', lastRenovationDate: data.propertyData?.lastMajorRenovationDate || '', isRented: data.propertyData?.currentlyRented ? 'Yes' : 'No', tenantName: data.propertyData?.currentTenantName || '', currentRent: data.propertyData?.currentMonthlyRentAmount || '', leaseEnd: data.propertyData?.leaseEndDate || '', ownerWillingToRent: data.propertyData?.ownerWillingToRent ? 'Yes' : 'No', expectedRent: data.propertyData?.expectedMonthlyRentAmount || '', schoolDistrict: data.propertyData?.schoolDistrict || '', neighborhoodRating: data.propertyData?.neighborhoodRating || 5, occupation: data.ownerData?.occupation || '', ownershipType: data.ownerData?.ownershipType || 'Individual', willingToSell: data.ownerData?.willingToSellProperty ? 'Yes' : 'No', desiredPrice: data.ownerData?.desiredSellingPrice || '', minPrice: data.ownerData?.minimumAcceptableSellingPrice || '', ownerAddress: data.ownerData?.mailingAddress || '', }); setIsEditing(false); } else if (newLocation) { setFormData(initialFormState); setIsEditing(true); } }, [data, newLocation]); const handleSave = () => { onSave(formData); if (data) setIsEditing(false); }; if (!isOpen) return null; const isCreating = !data && !!newLocation; const address = data?.propertyData?.propertyAddress || newLocation?.address || "Unknown Location"; const coords = data ? null : newLocation; // Helper for Inputs const RenderInput = ({ label, field, type = "text", placeholder, options, locked = false }) => { if (!isEditing) { return ( {formData[field] || "-"} ); } if (locked) { return (
{placeholder || "Not Applicable"}
); } return ( {options ? ( ) : ( setFormData({ ...formData, [field]: e.target.value })} placeholder={placeholder} className="w-full bg-zinc-50 dark:bg-black/20 border border-zinc-200 dark:border-white/10 rounded-lg py-2 px-3 text-sm text-zinc-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-blue-500 placeholder-zinc-400" /> )} ); }; return (
{/* Header */}
{/* Pattern */}
{isCreating ? New Entry : }

{loadingAddr ? "Fetching Address..." : address.split(',')[0]}

{loadingAddr ? "Locating..." : address}
{/* Body Content */}
{loadingAddr ? (
Resolving Location...
) : ( <> {/* Status Selector */} {isEditing && (
{["Neutral", "Hot Lead", "Customer", "Not Interested"].map(s => ( ))}
)} {/* SECTION 1: BASIC PROPERTY INFO */}

Property Basics

{/* SECTION 2: VALUES & CONDITION */}

Value & Condition

{/* SECTION 3: RENTAL STATUS (Conditional) */}

Rental Status

{formData.isRented === 'Yes' ? (
) : (
{formData.ownerWillingToRent !== 'No' && ( )}
)}
{/* SECTION 4: OWNER INTENT (Conditional) */}

Recall & Sales Intent

{formData.willingToSell === 'Yes' ? (
) : ( )}
{/* SECTION 5: OWNER CONTACT */}

Owner Contact

{/* SECTION 6: NOTES */}

Field Notes

{isEditing ? (