// Enhanced UI elements for RideShare app // Add floating action button for quick actions function addFloatingActionButton() { const fab = document.createElement('div'); fab.className = 'floating-action-button'; fab.innerHTML = ''; fab.style.position = 'absolute'; fab.style.bottom = '100px'; fab.style.right = '20px'; fab.style.width = '56px'; fab.style.height = '56px'; fab.style.borderRadius = '50%'; fab.style.backgroundColor = '#276EF1'; fab.style.color = 'white'; fab.style.display = 'flex'; fab.style.alignItems = 'center'; fab.style.justifyContent = 'center'; fab.style.boxShadow = '0 4px 8px rgba(0,0,0,0.2)'; fab.style.cursor = 'pointer'; fab.style.zIndex = '100'; fab.style.transition = 'transform 0.2s, background-color 0.2s'; // Add hover effect fab.addEventListener('mouseenter', () => { fab.style.transform = 'scale(1.1)'; }); fab.addEventListener('mouseleave', () => { fab.style.transform = 'scale(1)'; }); // Add click functionality to show quick actions menu let isMenuOpen = false; fab.addEventListener('click', () => { if (!isMenuOpen) { showQuickActionsMenu(fab); fab.innerHTML = ''; isMenuOpen = true; } else { hideQuickActionsMenu(); fab.innerHTML = ''; isMenuOpen = false; } }); document.querySelector('.map-container').appendChild(fab); return fab; } // Show quick actions menu function showQuickActionsMenu(fab) { const actions = [ { icon: 'fa-home', label: 'Home', action: () => selectSavedPlace('Home') }, { icon: 'fa-briefcase', label: 'Work', action: () => selectSavedPlace('Work') }, { icon: 'fa-clock', label: 'Schedule', action: () => document.getElementById('scheduleRideBtn').click() }, { icon: 'fa-history', label: 'History', action: () => document.getElementById('tripHistoryBtn').click() } ]; const menu = document.createElement('div'); menu.className = 'quick-actions-menu'; menu.style.position = 'absolute'; menu.style.bottom = '170px'; menu.style.right = '20px'; menu.style.display = 'flex'; menu.style.flexDirection = 'column'; menu.style.alignItems = 'flex-end'; menu.style.gap = '10px'; menu.style.zIndex = '99'; actions.forEach((action, index) => { const item = document.createElement('div'); item.className = 'quick-action-item'; item.innerHTML = `
${action.label}
`; item.style.display = 'flex'; item.style.alignItems = 'center'; item.style.gap = '10px'; item.style.opacity = '0'; item.style.transform = 'translateY(20px)'; item.style.transition = 'opacity 0.2s, transform 0.2s'; item.style.transitionDelay = `${index * 0.05}s`; const actionButton = item.querySelector('.action-button'); actionButton.style.width = '48px'; actionButton.style.height = '48px'; actionButton.style.borderRadius = '50%'; actionButton.style.backgroundColor = 'white'; actionButton.style.color = '#276EF1'; actionButton.style.display = 'flex'; actionButton.style.alignItems = 'center'; actionButton.style.justifyContent = 'center'; actionButton.style.boxShadow = '0 2px 5px rgba(0,0,0,0.2)'; actionButton.style.cursor = 'pointer'; const actionLabel = item.querySelector('.action-label'); actionLabel.style.backgroundColor = 'rgba(0,0,0,0.7)'; actionLabel.style.color = 'white'; actionLabel.style.padding = '5px 10px'; actionLabel.style.borderRadius = '4px'; actionLabel.style.fontSize = '14px'; item.addEventListener('click', () => { action.action(); hideQuickActionsMenu(); fab.innerHTML = ''; }); menu.appendChild(item); // Trigger animation after a small delay setTimeout(() => { item.style.opacity = '1'; item.style.transform = 'translateY(0)'; }, 10); }); menu.id = 'quickActionsMenu'; document.querySelector('.map-container').appendChild(menu); } // Hide quick actions menu function hideQuickActionsMenu() { const menu = document.getElementById('quickActionsMenu'); if (menu) { const items = menu.querySelectorAll('.quick-action-item'); items.forEach((item, index) => { item.style.opacity = '0'; item.style.transform = 'translateY(20px)'; item.style.transitionDelay = `${(items.length - index - 1) * 0.05}s`; }); setTimeout(() => { menu.remove(); }, items.length * 50 + 200); } } // Helper function to select a saved place function selectSavedPlace(place) { const savedPlaces = document.querySelectorAll('.saved-place'); savedPlaces.forEach(savedPlace => { if (savedPlace.querySelector('span').textContent === place) { savedPlace.click(); } }); } // Add a map style switcher function addMapStyleSwitcher() { const styleSwitch = document.createElement('div'); styleSwitch.className = 'map-style-switcher'; styleSwitch.innerHTML = `
Streets
Satellite
Dark
`; styleSwitch.style.position = 'absolute'; styleSwitch.style.top = '120px'; styleSwitch.style.right = '10px'; styleSwitch.style.backgroundColor = 'white'; styleSwitch.style.borderRadius = '8px'; styleSwitch.style.boxShadow = '0 2px 6px rgba(0,0,0,0.1)'; styleSwitch.style.overflow = 'hidden'; styleSwitch.style.zIndex = '100'; const styleOptions = styleSwitch.querySelectorAll('.style-option'); styleOptions.forEach(option => { option.style.padding = '8px 12px'; option.style.display = 'flex'; option.style.alignItems = 'center'; option.style.gap = '8px'; option.style.cursor = 'pointer'; option.style.transition = 'background-color 0.2s'; option.addEventListener('mouseenter', () => { if (!option.classList.contains('selected')) { option.style.backgroundColor = '#f5f5f5'; } }); option.addEventListener('mouseleave', () => { if (!option.classList.contains('selected')) { option.style.backgroundColor = 'white'; } }); option.addEventListener('click', () => { styleOptions.forEach(opt => { opt.classList.remove('selected'); opt.style.backgroundColor = 'white'; opt.style.fontWeight = 'normal'; }); option.classList.add('selected'); option.style.backgroundColor = '#f5f5f5'; option.style.fontWeight = 'bold'; // Change map style const style = option.getAttribute('data-style'); switch(style) { case 'streets': window.map.setStyle('mapbox://styles/mapbox/streets-v11'); break; case 'satellite': window.map.setStyle('mapbox://styles/mapbox/satellite-streets-v11'); break; case 'dark': window.map.setStyle('mapbox://styles/mapbox/dark-v10'); break; } }); }); document.querySelector('.map-container').appendChild(styleSwitch); } // Add a traffic toggle button function addTrafficToggle() { const trafficToggle = document.createElement('div'); trafficToggle.className = 'traffic-toggle'; trafficToggle.innerHTML = ` Traffic `; trafficToggle.style.position = 'absolute'; trafficToggle.style.top = '70px'; trafficToggle.style.left = '10px'; trafficToggle.style.backgroundColor = 'white'; trafficToggle.style.padding = '8px 12px'; trafficToggle.style.borderRadius = '20px'; trafficToggle.style.boxShadow = '0 2px 6px rgba(0,0,0,0.1)'; trafficToggle.style.display = 'flex'; trafficToggle.style.alignItems = 'center'; trafficToggle.style.gap = '8px'; trafficToggle.style.cursor = 'pointer'; trafficToggle.style.zIndex = '100'; trafficToggle.style.fontSize = '14px'; let trafficEnabled = false; trafficToggle.addEventListener('click', () => { trafficEnabled = !trafficEnabled; if (trafficEnabled) { trafficToggle.style.backgroundColor = '#276EF1'; trafficToggle.style.color = 'white'; // In a real app, this would add a traffic layer to the map showToast('Traffic layer enabled'); // Simulate traffic data if (window.map.getSource('route')) { window.map.setPaintProperty('route', 'line-color', [ 'step', ['random'], '#4CAF50', // Green for low traffic 0.3, '#FFC107', // Yellow for medium traffic 0.6, '#FF5722' // Red for heavy traffic ]); } } else { trafficToggle.style.backgroundColor = 'white'; trafficToggle.style.color = 'black'; // In a real app, this would remove the traffic layer showToast('Traffic layer disabled'); // Reset route color if (window.map.getSource('route')) { window.map.setPaintProperty('route', 'line-color', '#276EF1'); } } }); document.querySelector('.map-container').appendChild(trafficToggle); } // Add voice command functionality function addVoiceCommandButton() { const voiceButton = document.createElement('div'); voiceButton.className = 'voice-command-button'; voiceButton.innerHTML = ''; voiceButton.style.position = 'absolute'; voiceButton.style.bottom = '170px'; voiceButton.style.right = '20px'; voiceButton.style.width = '48px'; voiceButton.style.height = '48px'; voiceButton.style.borderRadius = '50%'; voiceButton.style.backgroundColor = 'white'; voiceButton.style.color = '#276EF1'; voiceButton.style.display = 'flex'; voiceButton.style.alignItems = 'center'; voiceButton.style.justifyContent = 'center'; voiceButton.style.boxShadow = '0 2px 6px rgba(0,0,0,0.2)'; voiceButton.style.cursor = 'pointer'; voiceButton.style.zIndex = '100'; voiceButton.style.transition = 'transform 0.2s, background-color 0.2s'; // Add hover effect voiceButton.addEventListener('mouseenter', () => { voiceButton.style.transform = 'scale(1.1)'; }); voiceButton.addEventListener('mouseleave', () => { voiceButton.style.transform = 'scale(1)'; }); // Add click functionality voiceButton.addEventListener('click', () => { // Simulate voice recognition voiceButton.style.backgroundColor = '#276EF1'; voiceButton.style.color = 'white'; voiceButton.innerHTML = ''; showToast('Listening for commands...'); // Simulate processing setTimeout(() => { voiceButton.style.backgroundColor = 'white'; voiceButton.style.color = '#276EF1'; voiceButton.innerHTML = ''; // Simulate a random command const commands = [ 'Take me home', 'Take me to work', 'Show my trip history', 'Schedule a ride' ]; const randomCommand = commands[Math.floor(Math.random() * commands.length)]; showToast(`Command recognized: "${randomCommand}"`); // Execute the simulated command setTimeout(() => { if (randomCommand === 'Take me home') { selectSavedPlace('Home'); } else if (randomCommand === 'Take me to work') { selectSavedPlace('Work'); } else if (randomCommand === 'Show my trip history') { document.getElementById('tripHistoryBtn').click(); } else if (randomCommand === 'Schedule a ride') { document.getElementById('scheduleRideBtn').click(); } }, 500); }, 2000); }); document.querySelector('.map-container').appendChild(voiceButton); } // Initialize enhanced UI function initEnhancedUI() { // Add with a slight delay to ensure the map is loaded setTimeout(() => { addFloatingActionButton(); addMapStyleSwitcher(); addTrafficToggle(); addVoiceCommandButton(); }, 1500); } // Export to window window.initEnhancedUI = initEnhancedUI;