MVP with new UX
This commit is contained in:
@@ -1,50 +1,238 @@
|
||||
/**
|
||||
* @ai-summary Main app component with routing
|
||||
* @ai-summary Main app component with routing and mobile navigation
|
||||
*/
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
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 { VehiclesPage } from './features/vehicles/pages/VehiclesPage';
|
||||
import { VehiclesMobileScreen } from './features/vehicles/mobile/VehiclesMobileScreen';
|
||||
import { VehicleDetailMobile } from './features/vehicles/mobile/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 { Vehicle } from './features/vehicles/types/vehicles.types';
|
||||
|
||||
|
||||
function App() {
|
||||
const { isLoading, isAuthenticated, loginWithRedirect } = useAuth0();
|
||||
|
||||
// Mobile navigation state - detect mobile screen size with responsive updates
|
||||
const [mobileMode, setMobileMode] = useState(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
return window.innerWidth <= 768;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
const [activeScreen, setActiveScreen] = useState("Vehicles");
|
||||
const [selectedVehicle, setSelectedVehicle] = useState<Vehicle | null>(null);
|
||||
|
||||
// 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);
|
||||
}, []);
|
||||
|
||||
// Mobile navigation items
|
||||
const mobileNavItems: NavigationItem[] = [
|
||||
{ key: "Dashboard", label: "Dashboard", icon: <HomeRoundedIcon /> },
|
||||
{ key: "Vehicles", label: "Vehicles", icon: <DirectionsCarRoundedIcon /> },
|
||||
{ key: "Log Fuel", label: "Log Fuel", icon: <LocalGasStationRoundedIcon /> },
|
||||
{ key: "Settings", label: "Settings", icon: <SettingsRoundedIcon /> },
|
||||
];
|
||||
|
||||
console.log('MotoVaultPro status:', { isLoading, isAuthenticated, mobileMode, userAgent: navigator.userAgent });
|
||||
|
||||
// Debug component for testing
|
||||
const DebugInfo = () => (
|
||||
<div className="fixed bottom-0 right-0 bg-black/80 text-white p-2 text-xs z-50 rounded-tl-lg">
|
||||
Mode: {mobileMode ? 'Mobile' : 'Desktop'} | Auth: {isAuthenticated ? 'Yes' : 'No'} | Screen: {typeof window !== 'undefined' ? window.innerWidth : 'N/A'}px
|
||||
</div>
|
||||
);
|
||||
|
||||
// Placeholder screens for mobile
|
||||
const DashboardScreen = () => (
|
||||
<div className="space-y-4">
|
||||
<GlassCard>
|
||||
<div className="text-center py-12">
|
||||
<h2 className="text-lg font-semibold text-slate-800 mb-2">Dashboard</h2>
|
||||
<p className="text-slate-500">Coming soon - Vehicle insights and analytics</p>
|
||||
</div>
|
||||
</GlassCard>
|
||||
</div>
|
||||
);
|
||||
|
||||
const LogFuelScreen = () => (
|
||||
<div className="space-y-4">
|
||||
<GlassCard>
|
||||
<div className="text-center py-12">
|
||||
<h2 className="text-lg font-semibold text-slate-800 mb-2">Log Fuel</h2>
|
||||
<p className="text-slate-500">Coming soon - Fuel logging functionality</p>
|
||||
</div>
|
||||
</GlassCard>
|
||||
</div>
|
||||
);
|
||||
|
||||
const SettingsScreen = () => (
|
||||
<div className="space-y-4">
|
||||
<GlassCard>
|
||||
<div className="text-center py-12">
|
||||
<h2 className="text-lg font-semibold text-slate-800 mb-2">Settings</h2>
|
||||
<p className="text-slate-500">Coming soon - App settings and preferences</p>
|
||||
</div>
|
||||
</GlassCard>
|
||||
</div>
|
||||
);
|
||||
|
||||
if (isLoading) {
|
||||
if (mobileMode) {
|
||||
return (
|
||||
<ThemeProvider theme={md3Theme}>
|
||||
<CssBaseline />
|
||||
<Layout mobileMode={true}>
|
||||
<div className="flex items-center justify-center h-64">
|
||||
<div className="text-slate-500">Loading...</div>
|
||||
</div>
|
||||
</Layout>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="flex items-center justify-center min-h-screen">
|
||||
<div className="text-lg">Loading...</div>
|
||||
</div>
|
||||
<ThemeProvider theme={md3Theme}>
|
||||
<CssBaseline />
|
||||
<div className="flex items-center justify-center min-h-screen">
|
||||
<div className="text-lg">Loading...</div>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
if (!isAuthenticated) {
|
||||
if (mobileMode) {
|
||||
return (
|
||||
<ThemeProvider theme={md3Theme}>
|
||||
<CssBaseline />
|
||||
<Layout mobileMode={true}>
|
||||
<div className="space-y-6 flex flex-col items-center justify-center min-h-[400px]">
|
||||
<div className="text-center">
|
||||
<h1 className="text-2xl font-bold text-slate-800 mb-3">Welcome to MotoVaultPro</h1>
|
||||
<p className="text-slate-600 mb-6 text-sm">Your personal vehicle management platform</p>
|
||||
<button
|
||||
onClick={() => loginWithRedirect()}
|
||||
className="h-12 px-8 rounded-2xl text-white font-medium shadow-lg active:scale-[0.99] transition bg-gradient-moto"
|
||||
>
|
||||
Login to Continue
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<DebugInfo />
|
||||
</Layout>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="flex items-center justify-center min-h-screen bg-gray-50">
|
||||
<div className="text-center">
|
||||
<h1 className="text-4xl font-bold text-gray-900 mb-4">MotoVaultPro</h1>
|
||||
<p className="text-gray-600 mb-8">Your personal vehicle management platform</p>
|
||||
<Button onClick={() => loginWithRedirect()}>
|
||||
Login to Continue
|
||||
</Button>
|
||||
<ThemeProvider theme={md3Theme}>
|
||||
<CssBaseline />
|
||||
<div className="flex items-center justify-center min-h-screen bg-gray-50">
|
||||
<div className="text-center max-w-md mx-auto px-6">
|
||||
<h1 className="text-4xl font-bold text-gray-900 mb-4">MotoVaultPro</h1>
|
||||
<p className="text-gray-600 mb-8">Your personal vehicle management platform</p>
|
||||
<Button onClick={() => loginWithRedirect()}>
|
||||
Login to Continue
|
||||
</Button>
|
||||
</div>
|
||||
<DebugInfo />
|
||||
</div>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
// Mobile app rendering
|
||||
if (mobileMode) {
|
||||
return (
|
||||
<ThemeProvider theme={md3Theme}>
|
||||
<CssBaseline />
|
||||
<Layout mobileMode={true}>
|
||||
<AnimatePresence mode="wait">
|
||||
{activeScreen === "Dashboard" && (
|
||||
<motion.div key="dashboard" initial={{opacity:0, y:8}} animate={{opacity:1, y:0}} exit={{opacity:0, y:-8}}>
|
||||
<DashboardScreen />
|
||||
</motion.div>
|
||||
)}
|
||||
{activeScreen === "Vehicles" && (
|
||||
<motion.div key="vehicles" initial={{opacity:0, y:8}} animate={{opacity:1, y:0}} exit={{opacity:0, y:-8}} className="space-y-6">
|
||||
{selectedVehicle ? (
|
||||
<VehicleDetailMobile
|
||||
vehicle={selectedVehicle}
|
||||
onBack={() => setSelectedVehicle(null)}
|
||||
onLogFuel={() => setActiveScreen("Log Fuel")}
|
||||
/>
|
||||
) : (
|
||||
<VehiclesMobileScreen
|
||||
onVehicleSelect={(vehicle) => setSelectedVehicle(vehicle)}
|
||||
/>
|
||||
)}
|
||||
</motion.div>
|
||||
)}
|
||||
{activeScreen === "Log Fuel" && (
|
||||
<motion.div key="logfuel" initial={{opacity:0, y:8}} animate={{opacity:1, y:0}} exit={{opacity:0, y:-8}}>
|
||||
<LogFuelScreen />
|
||||
</motion.div>
|
||||
)}
|
||||
{activeScreen === "Settings" && (
|
||||
<motion.div key="settings" initial={{opacity:0, y:8}} animate={{opacity:1, y:0}} exit={{opacity:0, y:-8}}>
|
||||
<SettingsScreen />
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
<DebugInfo />
|
||||
</Layout>
|
||||
|
||||
<BottomNavigation
|
||||
items={mobileNavItems}
|
||||
activeItem={activeScreen}
|
||||
onItemSelect={setActiveScreen}
|
||||
/>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
// Desktop app rendering (fallback)
|
||||
return (
|
||||
<Layout>
|
||||
<Routes>
|
||||
<Route path="/" element={<Navigate to="/vehicles" replace />} />
|
||||
<Route path="/vehicles" element={<VehiclesPage />} />
|
||||
<Route path="/vehicles/:id" element={<div>Vehicle Details (TODO)</div>} />
|
||||
<Route path="/fuel-logs" element={<div>Fuel Logs (TODO)</div>} />
|
||||
<Route path="/maintenance" element={<div>Maintenance (TODO)</div>} />
|
||||
<Route path="/stations" element={<div>Stations (TODO)</div>} />
|
||||
<Route path="*" element={<Navigate to="/vehicles" replace />} />
|
||||
</Routes>
|
||||
</Layout>
|
||||
<ThemeProvider theme={md3Theme}>
|
||||
<CssBaseline />
|
||||
<Layout mobileMode={false}>
|
||||
<Routes>
|
||||
<Route path="/" element={<Navigate to="/vehicles" replace />} />
|
||||
<Route path="/vehicles" element={<VehiclesPage />} />
|
||||
<Route path="/vehicles/:id" element={<div>Vehicle Details (TODO)</div>} />
|
||||
<Route path="/fuel-logs" element={<div>Fuel Logs (TODO)</div>} />
|
||||
<Route path="/maintenance" element={<div>Maintenance (TODO)</div>} />
|
||||
<Route path="/stations" element={<div>Stations (TODO)</div>} />
|
||||
<Route path="*" element={<Navigate to="/vehicles" replace />} />
|
||||
</Routes>
|
||||
<DebugInfo />
|
||||
</Layout>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user