import { useEffect, useState } from 'react' import { X, Navigation, Plus, Bookmark, Share2 } from 'lucide-react' import toast from 'react-hot-toast' import { useStore } from '../store' import { fetchElevation } from '../api' /** Meters to feet */ const M_TO_FT = 3.28084 /** Build display address from raw result data */ function buildAddress(place) { if (place.address) return place.address const raw = place.raw || {} const parts = [raw.street, raw.city, raw.state, raw.postcode].filter(Boolean) return parts.join(', ') || null } export default function PlaceDetail() { const selectedPlace = useStore((s) => s.selectedPlace) const clearSelectedPlace = useStore((s) => s.clearSelectedPlace) const startDirections = useStore((s) => s.startDirections) const addStop = useStore((s) => s.addStop) const stops = useStore((s) => s.stops) const geoPermission = useStore((s) => s.geoPermission) const [elevResult, setElevResult] = useState({ lat: null, lon: null, value: null }) const [isMobile, setIsMobile] = useState(false) useEffect(() => { const check = () => setIsMobile(window.innerWidth < 768) check() window.addEventListener('resize', check) return () => window.removeEventListener('resize', check) }, []) // Fetch elevation when place changes const placeLat = selectedPlace?.lat const placeLon = selectedPlace?.lon useEffect(() => { if (placeLat == null || placeLon == null) return let cancelled = false fetchElevation(placeLat, placeLon).then((h) => { if (!cancelled) setElevResult({ lat: placeLat, lon: placeLon, value: h }) }) return () => { cancelled = true } }, [placeLat, placeLon]) // Derive elevation/loading from comparing result to current place const elevLoading = placeLat != null && (elevResult.lat !== placeLat || elevResult.lon !== placeLon) const elevation = !elevLoading ? elevResult.value : null if (!selectedPlace) return null const address = buildAddress(selectedPlace) const elevFeet = elevation != null ? Math.round(elevation * M_TO_FT) : null const raw = selectedPlace.raw || {} // Check if place is already in stops const existingStopIndex = stops.findIndex( (s) => Math.abs(s.lat - selectedPlace.lat) < 0.00001 && Math.abs(s.lon - selectedPlace.lon) < 0.00001 ) const handleDirections = () => { startDirections(selectedPlace) if (geoPermission !== 'granted' && stops.length === 0) { toast('Set a starting point to get directions', { icon: '\u{1F4CD}' }) } } const handleAddStop = () => { addStop({ lat: selectedPlace.lat, lon: selectedPlace.lon, name: selectedPlace.name, source: selectedPlace.source, matchCode: selectedPlace.matchCode, }) clearSelectedPlace() } const handleSave = () => { toast('Saved places coming soon') } const handleShare = () => { const text = [ selectedPlace.name, address, `${selectedPlace.lat.toFixed(6)}, ${selectedPlace.lon.toFixed(6)}`, ].filter(Boolean).join('\n') navigator.clipboard.writeText(text).then( () => toast('Copied to clipboard'), () => toast.error('Failed to copy') ) } const panelContent = ( <> {/* Close button */} {/* Place name */}
{address}
)} {/* Coordinates + elevation */}