import { useRef, useCallback, useEffect, useState } from 'react' import { LogIn, LogOut, Footprints, Bike, Car, Shield, AlertTriangle, Zap, X, MapPin, Target } from 'lucide-react' import ThemePicker from './ThemePicker' import { useStore, usePanelState } from '../store' import { hasFeature } from '../config' import SearchBar from './SearchBar' import ManeuverList from './ManeuverList' import ContactList from './ContactList' import { PlaceCard } from './PlaceCard' import DirectionsPanel from './DirectionsPanel' import PlaceDetail from './PlaceDetail' const TRAVEL_MODES = [ { id: 'auto', label: 'Drive', Icon: Car }, { id: 'foot', label: 'Foot', Icon: Footprints }, { id: 'mtb', label: 'MTB', Icon: Bike }, { id: 'atv', label: 'ATV', Icon: Car }, { id: 'vehicle', label: '4x4', Icon: Car }, ] const BOUNDARY_MODES = [ { id: 'strict', label: 'Strict', Icon: Shield, title: 'Avoid barriers' }, { id: 'pragmatic', label: 'Cross', Icon: AlertTriangle, title: 'Cross with penalty' }, { id: 'emergency', label: 'Ignore', Icon: Zap, title: 'Ignore barriers' }, ] export default function Panel({ onClearRoute }) { const selectedPlace = useStore((s) => s.selectedPlace) const clearSelectedPlace = useStore((s) => s.clearSelectedPlace) const routeStart = useStore((s) => s.routeStart) const routeEnd = useStore((s) => s.routeEnd) const routeMode = useStore((s) => s.routeMode) const boundaryMode = useStore((s) => s.boundaryMode) const routeResult = useStore((s) => s.routeResult) const routeLoading = useStore((s) => s.routeLoading) const setRouteMode = useStore((s) => s.setRouteMode) const setBoundaryMode = useStore((s) => s.setBoundaryMode) const pickingRouteField = useStore((s) => s.pickingRouteField) const setPickingRouteField = useStore((s) => s.setPickingRouteField) const clearRoute = useStore((s) => s.clearRoute) const sheetState = useStore((s) => s.sheetState) const setSheetState = useStore((s) => s.setSheetState) const activeTab = useStore((s) => s.activeTab) const auth = useStore((s) => s.auth) const setActiveTab = useStore((s) => s.setActiveTab) const directionsMode = useStore((s) => s.directionsMode) const setDirectionsMode = useStore((s) => s.setDirectionsMode) const panelState = usePanelState() const [isMobile, setIsMobile] = useState(false) const sheetRef = useRef(null) const dragStartY = useRef(0) const dragStartState = useRef('half') const showContacts = hasFeature('has_contacts') && auth.authenticated useEffect(() => { const check = () => setIsMobile(window.innerWidth < 768) check() window.addEventListener('resize', check) return () => window.removeEventListener('resize', check) }, []) const handleLogin = () => { window.location.href = '/outpost.goauthentik.io/start?rd=%2F' } const handleLogout = () => { window.location.href = 'https://auth.echo6.co/if/flow/default-invalidation-flow/?next=https://navi.echo6.co/' } const handleTouchStart = useCallback((e) => { dragStartY.current = e.touches[0].clientY dragStartState.current = sheetState }, [sheetState]) const handleTouchEnd = useCallback((e) => { const deltaY = e.changedTouches[0].clientY - dragStartY.current if (Math.abs(deltaY) < 30) return if (deltaY < 0) { if (dragStartState.current === 'collapsed') setSheetState('half') else if (dragStartState.current === 'half') setSheetState('full') } else { if (dragStartState.current === 'full') setSheetState('half') else if (dragStartState.current === 'half') setSheetState('collapsed') } }, [setSheetState]) const handleClearRoute = () => { clearRoute() onClearRoute?.() } const showPreviewCard = panelState.startsWith('PREVIEW') const hasRoutePoints = routeStart || routeEnd const showRouteSection = hasRoutePoints || routeResult || routeLoading const showEmptyState = panelState === 'IDLE' && !hasRoutePoints // Show side panel place card when building route (either mode) and place is selected const showSidePlaceCard = (directionsMode || showRouteSection) && selectedPlace const routesContent = directionsMode ? ( // Directions mode: just the directions panel, place card is shown in side panel { setDirectionsMode(false) onClearRoute?.() }} /> ) : ( <> {showPreviewCard && selectedPlace && !showRouteSection && (
)} {showRouteSection && (
Route
{routeStart?.name || 'Click pin to pick start'}
{routeEnd?.name || 'Click pin to pick destination'}
{TRAVEL_MODES.map((m) => { const active = routeMode === m.id return ( ) })}
{routeMode !== 'auto' && (
{BOUNDARY_MODES.map((m) => { const active = boundaryMode === m.id return ( ) })}
)}
)} {showEmptyState && (

Search or tap the map to explore

)} ) const content = ( <> {showContacts && (
)} {(!showContacts || activeTab === 'routes') ? routesContent : } ) const header = (

Navi

{auth.loaded && ( auth.authenticated ? ( ) : ( ) )}
) // Side panel for place card during directions mode (desktop only) const sidePlaceCardPanel = showSidePlaceCard && !isMobile && (
{selectedPlace?.name || 'Place Info'}
{/* Use PlaceCard in compact preview mode */}
) // Mobile overlay for place card during directions mode const mobilePlaceCardOverlay = showSidePlaceCard && isMobile && (
{selectedPlace?.name || 'Place Info'}
) if (!isMobile) { return ( <>
{header} {content}
{sidePlaceCardPanel} ) } const sheetHeights = { collapsed: 'h-12', half: 'h-[45vh]', full: 'h-[85vh]', } return (
{ if (sheetState === 'collapsed') setSheetState('half') else if (sheetState === 'half') setSheetState('full') else setSheetState('half') }} >
{sheetState !== 'collapsed' && (
{header} {content} {mobilePlaceCardOverlay}
)}
) }