UNPKG

@naarni/design-system

Version:

Naarni React Native Design System for EV Fleet Apps

156 lines (147 loc) 5.73 kB
import React, { useState, useRef } from 'react'; import { View, TouchableOpacity, StyleSheet } from 'react-native'; import { Icon } from '../Icon'; import { Text } from '../Text'; import { Card } from '../Card/Card'; import MapComponent from './Map'; import { styles as mapStyles } from './styles'; const EnhancedMap = ({ showControls = true, showVehicleInfo = true, selectedVehicle, onVehicleSelect, vehicles = [], onVehiclePress, ...mapProps }) => { const mapRef = useRef(null); const [isVehicleInfoVisible, setIsVehicleInfoVisible] = useState(false); // Debug logging (reduced for stability) console.log('🗺️ EnhancedMap: Vehicles:', vehicles.length); const handleVehiclePress = (vehicle) => { try { onVehicleSelect?.(vehicle); setIsVehicleInfoVisible(true); onVehiclePress?.(vehicle); } catch (error) { console.error('EnhancedMap vehicle press error:', error); } }; const handleFitToVehicles = () => { try { mapRef.current?.fitToVehicles(); } catch (error) { console.error('Fit to vehicles error:', error); } }; const handleFitToSelectedVehicle = () => { try { if (selectedVehicle) { mapRef.current?.fitToVehicle(selectedVehicle); } } catch (error) { console.error('Fit to selected vehicle error:', error); } }; const handleClearSelection = () => { try { onVehicleSelect?.(null); setIsVehicleInfoVisible(false); } catch (error) { console.error('Clear selection error:', error); } }; const renderControls = () => { if (!showControls) return null; return (<View style={mapStyles.controlsContainer}> <TouchableOpacity style={mapStyles.controlButton} onPress={handleFitToVehicles} testID="fit-to-vehicles-button"> <Icon name="map-marker-multiple" size={20} color="#007AFF"/> </TouchableOpacity> {selectedVehicle && (<TouchableOpacity style={mapStyles.controlButton} onPress={handleFitToSelectedVehicle} testID="fit-to-selected-vehicle-button"> <Icon name="map-marker" size={20} color="#007AFF"/> </TouchableOpacity>)} {selectedVehicle && (<TouchableOpacity style={mapStyles.controlButton} onPress={handleClearSelection} testID="clear-selection-button"> <Icon name="close" size={20} color="#FF3B30"/> </TouchableOpacity>)} </View>); }; const renderVehicleInfo = () => { if (!showVehicleInfo || !selectedVehicle || !isVehicleInfoVisible) return null; return (<Card style={mapStyles.vehicleInfo}> <View style={styles.vehicleHeader}> <Text variant="h6" style={styles.vehicleName}> {selectedVehicle.name || 'Vehicle'} </Text> <TouchableOpacity onPress={handleClearSelection}> <Icon name="close" size={16} color="#666"/> </TouchableOpacity> </View> {selectedVehicle.description && (<Text variant="body2" color="#666" style={styles.vehicleDescription}> {selectedVehicle.description} </Text>)} <View style={styles.vehicleDetails}> <View style={styles.detailRow}> <Text variant="caption" color="#666">Location:</Text> <Text variant="body2"> {selectedVehicle.latitude.toFixed(6)}, {selectedVehicle.longitude.toFixed(6)} </Text> </View> {selectedVehicle.speed !== undefined && (<View style={styles.detailRow}> <Text variant="caption" color="#666">Speed:</Text> <Text variant="body2">{selectedVehicle.speed} km/h</Text> </View>)} {selectedVehicle.battery !== undefined && (<View style={styles.detailRow}> <Text variant="caption" color="#666">Battery:</Text> <Text variant="body2" color={selectedVehicle.battery < 20 ? '#FF3B30' : '#34C759'}> {selectedVehicle.battery}% </Text> </View>)} {selectedVehicle.status && (<View style={styles.detailRow}> <Text variant="caption" color="#666">Status:</Text> <Text variant="body2" style={styles.statusText}> {selectedVehicle.status} </Text> </View>)} {selectedVehicle.lastUpdate && (<View style={styles.detailRow}> <Text variant="caption" color="#666">Last Update:</Text> <Text variant="body2"> {selectedVehicle.lastUpdate.toLocaleTimeString()} </Text> </View>)} </View> </Card>); }; return (<View style={styles.container}> <MapComponent ref={mapRef} vehicles={vehicles} onVehiclePress={handleVehiclePress} {...mapProps}/> {renderControls()} {renderVehicleInfo()} </View>); }; const styles = StyleSheet.create({ container: { flex: 1, }, vehicleHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8, }, vehicleName: { flex: 1, marginRight: 8, }, vehicleDescription: { marginBottom: 12, }, vehicleDetails: { gap: 4, }, detailRow: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', }, statusText: { textTransform: 'capitalize', }, }); export default EnhancedMap;