diff --git a/src/components/MapView.jsx b/src/components/MapView.jsx index 9cc0498..31eb6cb 100644 --- a/src/components/MapView.jsx +++ b/src/components/MapView.jsx @@ -964,6 +964,13 @@ const MapView = forwardRef(function MapView(_, ref) { } } }) + // Initialize mapCenter immediately when map loads (Fix 1: search viewport) + map.once('load', () => { + const center = map.getCenter() + const zoom = map.getZoom() + setMapCenter({ lat: center.lat, lon: center.lng, zoom }) + }) + map.on('load', () => { map.addSource(ROUTE_SOURCE, { type: 'geojson', diff --git a/src/components/Panel.jsx b/src/components/Panel.jsx index d06c1de..9cc28da 100644 --- a/src/components/Panel.jsx +++ b/src/components/Panel.jsx @@ -32,7 +32,7 @@ export default function Panel({ onManeuverClick }) { const activeTab = useStore((s) => s.activeTab) const setActiveTab = useStore((s) => s.setActiveTab) - const panelState = usePanelState() + const { hasPreview, routeState } = usePanelState() const [isMobile, setIsMobile] = useState(false) const [optimizing, setOptimizing] = useState(false) @@ -126,11 +126,11 @@ export default function Panel({ onManeuverClick }) { const showOptimize = effectiveCount >= 3 - // Determine what to show based on panel state - const showPreviewCard = panelState === 'PREVIEW' || panelState === 'PREVIEW_ROUTING' - const showRouteSection = panelState === 'ROUTING' || panelState === 'PREVIEW_ROUTING' || panelState === 'ROUTE_CALCULATED' - const showManeuvers = panelState === 'ROUTE_CALCULATED' - const showEmptyState = panelState === 'IDLE' + // Determine what to show based on panel state (preview and route are now orthogonal) + const showPreviewCard = hasPreview + const showRouteSection = routeState === 'ROUTING' || routeState === 'CALCULATED' + const showManeuvers = routeState === 'CALCULATED' + const showEmptyState = !hasPreview && routeState === 'NONE' // Routes tab content - now state-driven const routesContent = ( diff --git a/src/store.js b/src/store.js index 8ce6fcc..dcc84cd 100644 --- a/src/store.js +++ b/src/store.js @@ -1,4 +1,5 @@ import { create } from 'zustand' +import { shallow } from 'zustand/shallow' export const useStore = create((set, get) => ({ // ── Search state ── @@ -108,9 +109,6 @@ export const useStore = create((set, get) => ({ if (override) { localStorage.setItem('navi-theme-override', override) } else { - // GPS denied, no stops: add destination, show empty origin slot - clearStops() - addStop({ lat: place.lat, lon: place.lon, name: place.name, source: place.source, matchCode: place.matchCode }) localStorage.removeItem('navi-theme-override') } }, @@ -124,16 +122,14 @@ export const useStore = create((set, get) => ({ setActiveTab: (tab) => set({ activeTab: tab }), setEditingContact: (c) => set({ editingContact: c }), clearEditingContact: () => set({ editingContact: null }), -})) +}), shallow) // ── Panel state selector ── -// IDLE | PREVIEW | ROUTING | PREVIEW_ROUTING | ROUTE_CALCULATED +// Returns { hasPreview: boolean, routeState: 'NONE' | 'ROUTING' | 'CALCULATED' } +// Preview and route states are now orthogonal - preview can show alongside any route state export const usePanelState = () => { - return useStore((s) => { - if (s.route) return "ROUTE_CALCULATED" - if (s.selectedPlace && s.stops.length >= 1) return "PREVIEW_ROUTING" - if (s.selectedPlace) return "PREVIEW" - if (s.stops.length >= 1) return "ROUTING" - return "IDLE" - }) + return useStore((s) => ({ + hasPreview: !!s.selectedPlace, + routeState: s.route ? "CALCULATED" : (s.stops.length >= 1 ? "ROUTING" : "NONE") + }), shallow) }