/** * @license * SPDX-License-Identifier: Apache-2.0 */ import { useState, useEffect, lazy, Suspense } from 'react'; import { BrowserRouter as Router, Routes, Route, Link, useLocation } from 'react-router-dom'; import { motion } from 'framer-motion'; import LeafletMapView from './components/LeafletMapView'; import Sidebar from './components/Sidebar'; import { ThinSidebar } from './components/ThinSidebar'; import { Map, Settings, Info, User, ChevronDown, ChevronUp } from 'lucide-react'; const AIAssistant = lazy(() => import('./components/AIAssistant')); import { OnboardingModal } from './components/OnboardingModal'; import { TripHistory } from './components/TripHistory'; import { IncidentReportModal } from './components/IncidentReportModal'; import { RouteLoadingSkeleton } from './components/SkeletonLoader'; import { requestNotificationPermission, showRouteAlert } from './lib/notifications'; import { useKeyboardShortcuts } from './hooks'; import { getCached, setCache, generateRouteCacheKey } from './lib/routeCache'; import { geocode, getRoute } from './lib/api'; function MapTab({ isSidebarOpen, routeData, setRouteData, alternativeRoutes, setAlternativeRoutes, riskData, setRiskData, previousRouteData, setPreviousRouteData, previousRiskData, setPreviousRiskData, incidentsData, setIncidentsData, weather, setWeather, startLoc, setStartLoc, endLoc, setEndLoc, startQuery, setStartQuery, endQuery, setEndQuery, theme, setTheme, vehicleType, setVehicleType, showIncidents, setShowIncidents, showRoutePlayback, setShowRoutePlayback, playbackSpeed, setPlaybackSpeed, mapStyleType, setMapStyleType, activeLayers, setActiveLayers, waypoints, voiceNavEnabled, onOpenIncidentReport, onOpenTripHistory, onToggleVoiceNav }: any) { return (
{isSidebarOpen && ( )}
); } function SettingsTab({ theme, setTheme, vehicleType, setVehicleType, mapStyleType, setMapStyleType, userProfile, onLogout, onUpdateProfile, highContrast, setHighContrast }: any) { const [isEditingProfile, setIsEditingProfile] = useState(false); const [profileName, setProfileName] = useState(userProfile?.name || ''); const [profileEmail, setProfileEmail] = useState(userProfile?.email || ''); const [selectedAvatar, setSelectedAvatar] = useState(userProfile?.photo || ''); const avatarOptions = [ { id: 'avataaars', label: 'Avatar', url: (name: string) => `https://api.dicebear.com/7.x/avataaars/svg?seed=${encodeURIComponent(name)}` }, { id: 'male', label: 'Male', url: (name: string) => `https://api.dicebear.com/7.x/personas/svg?seed=${encodeURIComponent(name)}&backgroundColor=b6e3f4` }, { id: 'female', label: 'Female', url: (name: string) => `https://api.dicebear.com/7.x/personas/svg?seed=${encodeURIComponent(name)}&backgroundColor=ffd5dc` }, { id: 'children', label: 'Children', url: (name: string) => `https://api.dicebear.com/7.x/croodles/svg?seed=${encodeURIComponent(name)}` }, { id: 'identicon', label: 'Abstract', url: (name: string) => `https://api.dicebear.com/7.x/identicon/svg?seed=${encodeURIComponent(name)}` }, { id: 'micah', label: 'Micah', url: (name: string) => `https://api.dicebear.com/7.x/micah/svg?seed=${encodeURIComponent(name)}` }, { id: 'miniavs', label: 'Mini', url: (name: string) => `https://api.dicebear.com/7.x/miniavs/svg?seed=${encodeURIComponent(name)}` }, { id: 'pixel-art', label: 'Pixel', url: (name: string) => `https://api.dicebear.com/7.x/pixel-art/svg?seed=${encodeURIComponent(name)}` } ]; useEffect(() => { setProfileName(userProfile?.name || ''); setProfileEmail(userProfile?.email || ''); setSelectedAvatar(userProfile?.photo || ''); }, [userProfile]); const handleSaveProfile = () => { if (profileName.trim()) { const photo = selectedAvatar || avatarOptions[0].url(profileName); onUpdateProfile(profileName, profileEmail, photo); setIsEditingProfile(false); } }; const handleDeleteProfile = () => { if (confirm('Are you sure you want to delete your profile?')) { onLogout(); } }; const handleClearAllData = () => { if (confirm('This will clear all saved locations, recent searches, and your profile. Continue?')) { localStorage.removeItem('savedLocations'); localStorage.removeItem('recentSearches'); localStorage.removeItem('userProfile'); onLogout(); } }; const getAvatarUrl = (avatarId: string) => { const avatar = avatarOptions.find(a => a.id === avatarId); return avatar ? avatar.url(profileName || 'user') : avatarOptions[0].url(profileName || 'user'); }; return (
{/* Header */}

Settings

Manage your profile and preferences

{/* User Profile Section */}

User Profile

Manage your personal information

{userProfile ? ( <> {isEditingProfile ? (
{/* Avatar Selection */}
{avatarOptions.map((avatar) => ( ))}
{/* Name Input */}
{ setProfileName(e.target.value); // Update avatar preview with new name if (!selectedAvatar || avatarOptions.some(a => selectedAvatar.includes(a.id))) { const currentAvatar = avatarOptions.find(a => selectedAvatar?.includes(a.id)); if (currentAvatar) { setSelectedAvatar(currentAvatar.url(e.target.value)); } } }} className="w-full px-4 py-3 bg-zinc-50 dark:bg-zinc-950 border border-zinc-200 dark:border-zinc-800 rounded-lg text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-emerald-500/50" placeholder="Enter your name" />
{/* Email Input */}
setProfileEmail(e.target.value)} className="w-full px-4 py-3 bg-zinc-50 dark:bg-zinc-950 border border-zinc-200 dark:border-zinc-800 rounded-lg text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-emerald-500/50" placeholder="Enter your email" />
{/* Preview */}
Preview

{profileName || 'Your Name'}

{profileEmail || 'your@email.com'}

Preview

) : (
{userProfile.photo ? ( Profile ) : (
{userProfile.name?.charAt(0).toUpperCase()}
)}

{userProfile.name}

{userProfile.email}

Active Profile

)} ) : (

Create Your Profile

Set up a profile to save your preferences, locations, and travel history.

setProfileName(e.target.value)} className="px-4 py-2 bg-zinc-50 dark:bg-zinc-950 border border-zinc-200 dark:border-zinc-800 rounded-lg text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-emerald-500/50 w-64" placeholder="Enter your name" />
)}
{/* Appearance Settings */}

Appearance

Customize how SafeRoute looks

Theme

Switch between light and dark mode

High Contrast Mode

Increase contrast for better visibility

Voice Navigation

Enable spoken turn-by-turn directions

{/* Preferences */}

Preferences

Set your default travel preferences

Default Vehicle

Map Style

{[ { value: 'default', label: 'Default', icon: }, { value: 'satellite', label: 'Satellite', icon: }, { value: 'navigation', label: 'Navigation', icon: } ].map((style) => ( ))}
{/* Data Management */}

Data Management

Manage your saved data and history

Saved Locations

Your bookmarked places

{((): number => { try { return JSON.parse(localStorage.getItem('savedLocations') || '[]').length; } catch { return 0; } })()} saved

Recent Searches

Your search history

{((): number => { try { return JSON.parse(localStorage.getItem('recentSearches') || '[]').length; } catch { return 0; } })()} searches
{/* Version Info */}

SafeRoute v1.0.0

Made-with-Ayush

); } function AboutTab() { return (
{/* Hero Section */}

About SafeRoute

An intelligent traffic safety platform that combines real-time routing, weather analysis, and AI-powered risk prediction to help you travel safer.

{/* Problem & Solution */}

The Problem

Road accidents claim over 1.3 million lives annually. Traditional navigation apps lack real-time safety insights, leaving drivers vulnerable to changing road conditions.

Our Solution

SafeRoute analyzes multiple risk factors including weather, traffic, time of day, and historical data to provide intelligent route recommendations.

{/* Key Features */}

Key Features

{[ { icon: ( ), title: 'Route Risk Analysis', desc: 'Dynamic color-coded routes showing real-time risk levels for each segment' }, { icon: ( ), title: 'Weather Integration', desc: 'Real-time weather data affecting route risk calculations automatically' }, { icon: ( ), title: 'AI Assistant', desc: 'Intelligent chatbot providing contextual safety advice and recommendations' }, { icon: ( ), title: 'Route Playback', desc: 'Visualize your entire route with animated playback feature' }, { icon: ( ), title: 'Multiple Profiles', desc: 'Save locations, view history, and customize preferences' }, { icon: ( ), title: 'Safety Score', desc: 'Overall route safety rating based on multiple risk factors' } ].map((feature, idx) => (
{feature.icon}

{feature.title}

{feature.desc}

))}
{/* How It Works */}

How It Works

{[ { step: '01', title: 'Enter Route', desc: 'Search for your origin and destination' }, { step: '02', title: 'Set Vehicle', desc: 'Choose driving or cycling mode' }, { step: '03', title: 'Analyze Risk', desc: 'Our AI calculates safety scores' }, { step: '04', title: 'Safe Travel', desc: 'Follow the safest route with live updates' } ].map((item, idx) => (
{item.step}

{item.title}

{item.desc}

{idx < 3 && (
)}
))}
{/* Technology Stack */}

Built With

{[ { name: 'React', icon: }, { name: 'Leaflet', icon: }, { name: 'OpenStreetMap', icon: }, { name: 'Express', icon: }, { name: 'Machine Learning', icon: }, { name: 'Generative AI', icon: }, { name: 'Data Analytics', icon: }, { name: 'Predictive Modeling', icon: }, { name: 'Real-Time Data', icon: } ].map((tech) => ( {tech.icon} {tech.name} ))}
{/* Closing */}
Made-with-Ayush

SafeRoute is designed to help you make informed decisions about your travel routes. Always drive safely and follow local traffic regulations.

); } export default function App() { const [routeData, setRouteData] = useState(null); const [alternativeRoutes, setAlternativeRoutes] = useState([]); const [riskData, setRiskData] = useState(null); const [previousRouteData, setPreviousRouteData] = useState(null); const [previousRiskData, setPreviousRiskData] = useState(null); const [incidentsData, setIncidentsData] = useState(null); const [weather, setWeather] = useState(null); const [startLoc, setStartLoc] = useState<[number, number] | null>(null); const [endLoc, setEndLoc] = useState<[number, number] | null>(null); const [startQuery, setStartQuery] = useState(''); const [endQuery, setEndQuery] = useState(''); const [showRoutePlayback, setShowRoutePlayback] = useState(false); const [playbackSpeed, setPlaybackSpeed] = useState(1); const [theme, setTheme] = useState<'dark' | 'light'>(() => { try { const saved = localStorage.getItem('theme'); return (saved === 'dark' || saved === 'light') ? saved : 'dark'; } catch { return 'dark'; } }); const [vehicleType, setVehicleType] = useState<'driving' | 'cycling'>(() => { try { const saved = localStorage.getItem('vehicleType'); return (saved === 'driving' || saved === 'cycling') ? saved : 'driving'; } catch { return 'driving'; } }); const [showIncidents, setShowIncidents] = useState(false); const [activeLayers, setActiveLayers] = useState([]); const [mapStyleType, setMapStyleType] = useState(() => { try { return localStorage.getItem('mapStyleType') || 'default'; } catch { return 'default'; } }); const [showHeader, setShowHeader] = useState(true); const [isSidebarOpen, setIsSidebarOpen] = useState(true); const [userProfile, setUserProfile] = useState(() => { try { const saved = localStorage.getItem('userProfile'); return saved ? JSON.parse(saved) : null; } catch { return null; } }); const [showOnboarding, setShowOnboarding] = useState(() => { try { return !localStorage.getItem('onboardingComplete'); } catch { return true; } }); const [showTripHistory, setShowTripHistory] = useState(false); const [incidentReportLoc, setIncidentReportLoc] = useState<[number, number] | null>(null); const [voiceNavEnabled, setVoiceNavEnabled] = useState(false); const [highContrast, setHighContrast] = useState(() => { try { return localStorage.getItem('highContrast') === 'true'; } catch { return false; } }); const handleLogin = (profile?: { name: string; email: string; photo?: string }) => { if (profile) { const user = { name: profile.name, email: profile.email, photo: profile.photo || `https://api.dicebear.com/7.x/avataaars/svg?seed=${encodeURIComponent(profile.name)}` }; setUserProfile(user); localStorage.setItem('userProfile', JSON.stringify(user)); } else { const mockUser = { name: 'Guest User', email: 'guest@example.com', photo: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Felix' }; setUserProfile(mockUser); localStorage.setItem('userProfile', JSON.stringify(mockUser)); } }; const handleLogout = () => { setUserProfile(null); localStorage.removeItem('userProfile'); }; const handleUpdateProfile = (name: string, email: string, photo: string) => { const user = { name, email, photo }; setUserProfile(user); localStorage.setItem('userProfile', JSON.stringify(user)); }; useEffect(() => { localStorage.setItem('theme', theme); if (theme === 'dark') { document.documentElement.classList.add('dark'); } else { document.documentElement.classList.remove('dark'); } }, [theme]); useEffect(() => { localStorage.setItem('vehicleType', vehicleType); }, [vehicleType]); useEffect(() => { localStorage.setItem('mapStyleType', mapStyleType); }, [mapStyleType]); useEffect(() => { localStorage.setItem('highContrast', String(highContrast)); if (highContrast) { document.documentElement.classList.add('high-contrast'); } else { document.documentElement.classList.remove('high-contrast'); } }, [highContrast]); const handleOnboardingComplete = () => { setShowOnboarding(false); localStorage.setItem('onboardingComplete', 'true'); requestNotificationPermission(); }; useKeyboardShortcuts([ { key: 'h', ctrl: true, handler: () => setHighContrast(prev => !prev), description: 'Toggle high contrast' }, { key: 'o', ctrl: true, handler: () => setShowOnboarding(true), description: 'Show onboarding' }, { key: 't', ctrl: true, handler: () => setShowTripHistory(true), description: 'Trip history' }, ]); return (
{ setEndLoc(loc); setEndQuery(name); }} currentEndLoc={endLoc} currentEndQuery={endQuery} />
setIncidentReportLoc(loc)} onOpenTripHistory={() => setShowTripHistory(true)} onToggleVoiceNav={(enabled: boolean) => setVoiceNavEnabled(enabled)} /> } /> } /> } />
{showOnboarding && } {showTripHistory && setShowTripHistory(false)} />} {incidentReportLoc && ( setIncidentReportLoc(null)} onSubmit={(report) => { console.log('Incident reported:', report); setIncidentReportLoc(null); }} /> )}
); }