/** * @ai-summary Main app component with routing and mobile navigation */ import { useState, useEffect, useTransition, useCallback, lazy } from 'react'; import { useQueryClient } from '@tanstack/react-query'; import { Routes, Route, Navigate } from 'react-router-dom'; import { useAuth0 } from '@auth0/auth0-react'; import { motion, AnimatePresence } from 'framer-motion'; import { ThemeProvider } from '@mui/material/styles'; import CssBaseline from '@mui/material/CssBaseline'; import HomeRoundedIcon from '@mui/icons-material/HomeRounded'; import DirectionsCarRoundedIcon from '@mui/icons-material/DirectionsCarRounded'; import LocalGasStationRoundedIcon from '@mui/icons-material/LocalGasStationRounded'; import SettingsRoundedIcon from '@mui/icons-material/SettingsRounded'; import { md3Theme } from './shared-minimal/theme/md3Theme'; import { Layout } from './components/Layout'; import { UnitsProvider } from './core/units/UnitsContext'; // Lazy load route components for better initial bundle size const VehiclesPage = lazy(() => import('./features/vehicles/pages/VehiclesPage').then(m => ({ default: m.VehiclesPage }))); const VehicleDetailPage = lazy(() => import('./features/vehicles/pages/VehicleDetailPage').then(m => ({ default: m.VehicleDetailPage }))); const SettingsPage = lazy(() => import('./pages/SettingsPage').then(m => ({ default: m.SettingsPage }))); const FuelLogsPage = lazy(() => import('./features/fuel-logs/pages/FuelLogsPage').then(m => ({ default: m.FuelLogsPage }))); const VehiclesMobileScreen = lazy(() => import('./features/vehicles/mobile/VehiclesMobileScreen').then(m => ({ default: m.VehiclesMobileScreen }))); const VehicleDetailMobile = lazy(() => import('./features/vehicles/mobile/VehicleDetailMobile').then(m => ({ default: m.VehicleDetailMobile }))); import { BottomNavigation, NavigationItem } from './shared-minimal/components/mobile/BottomNavigation'; import { GlassCard } from './shared-minimal/components/mobile/GlassCard'; import { Button } from './shared-minimal/components/Button'; import { RouteSuspense } from './components/SuspenseWrappers'; import { Vehicle } from './features/vehicles/types/vehicles.types'; import { FuelLogForm } from './features/fuel-logs/components/FuelLogForm'; import { FuelLogsList } from './features/fuel-logs/components/FuelLogsList'; import { FuelLogEditDialog } from './features/fuel-logs/components/FuelLogEditDialog'; import { useFuelLogs } from './features/fuel-logs/hooks/useFuelLogs'; import { FuelLogResponse, UpdateFuelLogRequest } from './features/fuel-logs/types/fuel-logs.types'; import { fuelLogsApi } from './features/fuel-logs/api/fuel-logs.api'; import { VehicleForm } from './features/vehicles/components/VehicleForm'; import { useOptimisticVehicles } from './features/vehicles/hooks/useOptimisticVehicles'; import { CreateVehicleRequest } from './features/vehicles/types/vehicles.types'; import { MobileSettingsScreen } from './features/settings/mobile/MobileSettingsScreen'; import { useNavigationStore, useUserStore } from './core/store'; import { useDataSync } from './core/hooks/useDataSync'; import { MobileDebugPanel } from './core/debug/MobileDebugPanel'; import { MobileErrorBoundary } from './core/error-boundaries/MobileErrorBoundary'; // Hoisted mobile screen components to stabilize identity and prevent remounts const DashboardScreen: React.FC = () => (

Dashboard

Coming soon - Vehicle insights and analytics

); const LogFuelScreen: React.FC = () => { const queryClient = useQueryClient(); const [editingLog, setEditingLog] = useState(null); const { goBack, canGoBack, navigateToScreen } = useNavigationStore(); useEffect(() => { console.log('[LogFuelScreen] Mounted'); return () => console.log('[LogFuelScreen] Unmounted'); }, []); let fuelLogs: FuelLogResponse[] | undefined, isLoading: boolean | undefined, error: any; try { const hookResult = useFuelLogs(); fuelLogs = hookResult.fuelLogs; isLoading = hookResult.isLoading; error = hookResult.error; } catch (hookError) { console.error('[LogFuelScreen] Hook error:', hookError); error = hookError; } const handleEdit = (log: FuelLogResponse) => { if (!log || !log.id) { console.error('[LogFuelScreen] Invalid log data for edit:', log); return; } try { setEditingLog(log); } catch (error) { console.error('[LogFuelScreen] Error setting editing log:', error); } }; const handleDelete = async (_logId: string) => { try { queryClient.invalidateQueries({ queryKey: ['fuelLogs'] }); queryClient.invalidateQueries({ queryKey: ['fuelLogsStats'] }); } catch (error) { console.error('Failed to refresh fuel logs after delete:', error); } }; const handleSaveEdit = async (id: string, data: UpdateFuelLogRequest) => { try { await fuelLogsApi.update(id, data); queryClient.invalidateQueries({ queryKey: ['fuelLogs'] }); queryClient.invalidateQueries({ queryKey: ['fuelLogsStats'] }); setEditingLog(null); } catch (error) { console.error('Failed to update fuel log:', error); throw error; } }; const handleCloseEdit = () => setEditingLog(null); if (error) { return (

Failed to load fuel logs

); } if (isLoading === undefined) { return (
Initializing fuel logs...
); } return (
{ // Refresh dependent data try { queryClient.invalidateQueries({ queryKey: ['fuelLogs'] }); queryClient.invalidateQueries({ queryKey: ['fuelLogsStats'] }); } catch {} // Navigate back if we have history; otherwise go to Vehicles if (canGoBack()) { goBack(); } else { navigateToScreen('Vehicles', { source: 'fuel-log-added' }); } }} />
{isLoading ? (
Loading fuel logs...
) : ( )}
); }; interface AddVehicleScreenProps { onBack: () => void; onAdded: () => void; } const AddVehicleScreen: React.FC = ({ onBack, onAdded }) => { const { optimisticCreateVehicle } = useOptimisticVehicles([]); const handleCreateVehicle = async (data: CreateVehicleRequest) => { try { await optimisticCreateVehicle(data); onAdded(); } catch (error) { console.error('Failed to create vehicle:', error); } }; return (

Add Vehicle

); }; function App() { const { isLoading, isAuthenticated, loginWithRedirect, user } = useAuth0(); const [_isPending, startTransition] = useTransition(); // Initialize data synchronization const { prefetchForNavigation } = useDataSync(); // Enhanced navigation and user state management const { activeScreen, vehicleSubScreen, navigateToScreen, navigateToVehicleSubScreen, goBack, canGoBack, } = useNavigationStore(); const { setUserProfile } = useUserStore(); // Mobile mode detection - detect mobile screen size with responsive updates const [mobileMode, setMobileMode] = useState(() => { if (typeof window !== 'undefined') { return window.innerWidth <= 768; } return false; }); const [selectedVehicle, setSelectedVehicle] = useState(null); const [showAddVehicle, setShowAddVehicle] = useState(false); // Update mobile mode on window resize useEffect(() => { const checkMobileMode = () => { const isMobile = window.innerWidth <= 768 || /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); console.log('Window width:', window.innerWidth, 'User agent mobile:', /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent), 'Mobile mode:', isMobile); setMobileMode(isMobile); }; // Check on mount checkMobileMode(); window.addEventListener('resize', checkMobileMode); return () => window.removeEventListener('resize', checkMobileMode); }, []); // Update user profile when authenticated useEffect(() => { if (isAuthenticated && user) { setUserProfile(user); } }, [isAuthenticated, user, setUserProfile]); // Handle mobile back button and navigation errors useEffect(() => { const handlePopState = (event: PopStateEvent) => { event.preventDefault(); if (canGoBack() && mobileMode) { goBack(); } }; if (mobileMode) { window.addEventListener('popstate', handlePopState); return () => window.removeEventListener('popstate', handlePopState); } return undefined; }, [goBack, canGoBack, mobileMode]); // Mobile navigation items const mobileNavItems: NavigationItem[] = [ { key: "Dashboard", label: "Dashboard", icon: }, { key: "Vehicles", label: "Vehicles", icon: }, { key: "Log Fuel", label: "Log Fuel", icon: }, { key: "Settings", label: "Settings", icon: }, ]; console.log('MotoVaultPro status:', { isLoading, isAuthenticated, mobileMode, activeScreen, vehicleSubScreen, userAgent: navigator.userAgent }); // Enhanced navigation handlers for mobile const handleVehicleSelect = useCallback((vehicle: Vehicle) => { setSelectedVehicle(vehicle); navigateToVehicleSubScreen('detail', vehicle.id, { source: 'vehicle-list' }); }, [navigateToVehicleSubScreen]); const handleAddVehicle = useCallback(() => { setShowAddVehicle(true); navigateToVehicleSubScreen('add', undefined, { source: 'vehicle-list' }); }, [navigateToVehicleSubScreen]); const handleBackToList = useCallback(() => { setSelectedVehicle(null); setShowAddVehicle(false); navigateToVehicleSubScreen('list', undefined, { source: 'back-navigation' }); }, [navigateToVehicleSubScreen]); const handleVehicleAdded = useCallback(() => { setShowAddVehicle(false); navigateToVehicleSubScreen('list', undefined, { source: 'vehicle-added' }); }, [navigateToVehicleSubScreen]); // Enhanced debug component const DebugInfo = () => ( ); // Mobile settings now uses the dedicated MobileSettingsScreen component const SettingsScreen = MobileSettingsScreen; if (isLoading) { if (mobileMode) { return (
Loading...
); } return (
Loading...
); } if (!isAuthenticated) { if (mobileMode) { return (

Welcome to MotoVaultPro

Your personal vehicle management platform

); } return (

MotoVaultPro

Your personal vehicle management platform

); } // Mobile app rendering if (mobileMode) { return ( {activeScreen === "Dashboard" && ( )} {activeScreen === "Vehicles" && ( {vehicleSubScreen === 'add' || showAddVehicle ? ( ) : selectedVehicle && (vehicleSubScreen === 'detail') ? ( navigateToScreen("Log Fuel")} /> ) : ( )} )} {activeScreen === "Log Fuel" && ( )} {activeScreen === "Settings" && ( )} startTransition(() => { // Prefetch data for the target screen prefetchForNavigation(screen); // Reset states first, then navigate to prevent race conditions if (screen !== 'Vehicles') { setSelectedVehicle(null); // Reset selected vehicle when leaving Vehicles } if (screen !== 'Vehicles' || vehicleSubScreen !== 'add') { setShowAddVehicle(false); // Reset add vehicle form when appropriate } // Navigate after state cleanup navigateToScreen(screen as any, { source: 'bottom-navigation' }); })} /> ); } // Desktop app rendering (fallback) return ( } /> Processing login...} /> } /> } /> } /> Maintenance (TODO)} /> Stations (TODO)} /> } /> } /> ); } export default App;