import React, { useState, useEffect, useRef } from 'react'; import { Menu, MapPin, User, ChevronRight, Car, Bike, Navigation, Clock, CreditCard, Star, Map as MapIcon, ShieldCheck } from 'lucide-react'; // Fórmula para calcular distancia entre dos coordenadas (Haversine) function calcularDistanciaKm(lat1, lon1, lat2, lon2) { const R = 6371; // Radio de la Tierra en km const dLat = (lat2 - lat1) * Math.PI / 180; const dLon = (lon2 - lon1) * Math.PI / 180; const a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) * Math.sin(dLon/2) * Math.sin(dLon/2); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); return R * c; } export default function AppPasajera() { const [vistaActiva, setVistaActiva] = useState('mapa'); // 'mapa', 'historial', 'perfil' const [destinoCoords, setDestinoCoords] = useState(null); const [direccionDestino, setDireccionDestino] = useState(''); const [buscandoDireccion, setBuscandoDireccion] = useState(false); const [distancia, setDistancia] = useState(0); const [vehiculoSeleccionado, setVehiculoSeleccionado] = useState('moto'); const [estadoViaje, setEstadoViaje] = useState('inicio'); // 'inicio', 'buscando', 'en_camino' const [conductorasActivas, setConductorasActivas] = useState(4); // Simulación de conductoras activas const mapContainerRef = useRef(null); const mapInstanceRef = useRef(null); const destinoMarkerRef = useRef(null); const polylineRef = useRef(null); // Coordenadas centrales de Trinidad, Beni (Origen fijo por ahora) const origenCoords = [-14.834, -64.900]; const TARIFA_POR_KM = 3.50; // Cargar e inicializar el mapa useEffect(() => { if (vistaActiva !== 'mapa' || estadoViaje !== 'inicio') return; const initMap = () => { if (!window.L || !mapContainerRef.current) return; // Evitar reinicializar si ya existe if (mapInstanceRef.current) { mapInstanceRef.current.invalidateSize(); return; } // Se añade attributionControl: false para ocultar la marca de Leaflet const map = window.L.map(mapContainerRef.current, { zoomControl: false, attributionControl: false }).setView(origenCoords, 14); mapInstanceRef.current = map; // Usamos CartoDB Voyager en lugar del default de OSM para evitar el Error 403 y tener mejor diseño window.L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png', { maxZoom: 19 }).addTo(map); // Marcador de Origen const pasajeraIcon = window.L.divIcon({ className: 'custom-icon', html: `
`, iconSize: [18, 18], iconAnchor: [9, 9] }); window.L.marker(origenCoords, { icon: pasajeraIcon }).addTo(map).bindPopup("Tu ubicación").openPopup(); // Evento: Tocar el mapa para elegir destino y obtener el nombre de la calle (Reverse Geocoding) map.on('click', async function(e) { const lat = e.latlng.lat; const lng = e.latlng.lng; setDestinoCoords([lat, lng]); setBuscandoDireccion(true); try { const response = await fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lng}`); const data = await response.json(); // Extraer el nombre de la calle, barrio o nombre general const nombreCalle = data.address.road || data.address.neighbourhood || data.address.suburb || "Calle sin nombre"; setDireccionDestino(nombreCalle); } catch (error) { setDireccionDestino("Ubicación seleccionada"); } finally { setBuscandoDireccion(false); } }); }; if (!window.L) { const link = document.createElement('link'); link.rel = 'stylesheet'; link.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css'; document.head.appendChild(link); const script = document.createElement('script'); script.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js'; script.onload = initMap; document.head.appendChild(script); } else { initMap(); } return () => { if (mapInstanceRef.current) { mapInstanceRef.current.off('click'); } }; }, [vistaActiva, estadoViaje]); // Actualizar marcadores y rutas cuando cambia el destino useEffect(() => { if (!mapInstanceRef.current || !destinoCoords) return; const map = mapInstanceRef.current; // Calcular distancia const dist = calcularDistanciaKm(origenCoords[0], origenCoords[1], destinoCoords[0], destinoCoords[1]); setDistancia(dist); // Crear o actualizar marcador de destino const destinoIcon = window.L.divIcon({ className: 'custom-icon', html: ``, iconSize: [18, 18], iconAnchor: [9, 9] }); if (destinoMarkerRef.current) { destinoMarkerRef.current.setLatLng(destinoCoords); } else { destinoMarkerRef.current = window.L.marker(destinoCoords, { icon: destinoIcon }).addTo(map); } // Trazar línea if (polylineRef.current) { polylineRef.current.setLatLngs([origenCoords, destinoCoords]); } else { polylineRef.current = window.L.polyline([origenCoords, destinoCoords], {color: '#8e44ad', weight: 4, dashArray: '10, 10'}).addTo(map); } // Ajustar vista para que se vean ambos puntos map.fitBounds([origenCoords, destinoCoords], { padding: [50, 50] }); }, [destinoCoords]); // Cálculo de tarifa: Redondear siempre hacia arriba al 0.5 más cercano (ej: 4.2 -> 4.5) const precioCalculado = distancia * TARIFA_POR_KM; const precioRedondeado = Math.ceil(precioCalculado * 2) / 2; const precioEstimado = Math.max(4, precioRedondeado).toFixed(2); // Tarifa mínima ajustada a 4 Bs const solicitarViaje = () => { if (!destinoCoords) { alert("Por favor, toca en el mapa a dónde quieres ir."); return; } setEstadoViaje('buscando'); setTimeout(() => setEstadoViaje('en_camino'), 3000); }; // VISTAS const renderHistorial = () => ({viaje.destino}
{viaje.fecha} • {viaje.conductora}
{viaje.precio}
+591 71234567
4.9
12
Destino
{buscandoDireccion ? "Buscando calle..." : direccionDestino}
Distancia
{distancia.toFixed(2)} km
Tarifa Estimada
Bs. {precioEstimado}
{conductorasActivas > 0 ? `Hay ${conductorasActivas} conductoras activas cerca de ti` : 'No hay conductoras activas en este momento'}
Notificando a conductoras cercanas.
> )} {estadoViaje === 'en_camino' && ( <>Llegará en 4 minutos a tu ubicación.
María Fernández
Moto Honda • 4.9
Placa: 234-PQR