feat: geolocalización GPS con Haversine para detectar zona automáticamente
This commit is contained in:
@@ -2,6 +2,7 @@ import { StatusBar } from 'expo-status-bar';
|
||||
import { StyleSheet, Text, View, TextInput, TouchableOpacity, ActivityIndicator, ScrollView, Alert, RefreshControl } from 'react-native';
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import * as Location from 'expo-location';
|
||||
|
||||
const API_URL = 'http://10.137.112.65:8000';
|
||||
|
||||
@@ -32,6 +33,7 @@ export default function App() {
|
||||
completed: true,
|
||||
});
|
||||
const [alertaOperativa, setAlertaOperativa] = useState(null);
|
||||
const [localizando, setLocalizando] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
cargarSesion();
|
||||
@@ -260,6 +262,38 @@ export default function App() {
|
||||
} catch {}
|
||||
};
|
||||
|
||||
const usarUbicacion = async () => {
|
||||
setLocalizando(true);
|
||||
try {
|
||||
const { status } = await Location.requestForegroundPermissionsAsync();
|
||||
if (status !== 'granted') {
|
||||
Alert.alert('Permiso denegado', 'Necesitamos acceso a tu ubicación para encontrar tu zona de recolección');
|
||||
setLocalizando(false);
|
||||
return;
|
||||
}
|
||||
const location = await Location.getCurrentPositionAsync({ accuracy: Location.Accuracy.High });
|
||||
const { latitude, longitude } = location.coords;
|
||||
|
||||
const res = await fetch(
|
||||
`${API_URL}/domicilios/ruta-por-coordenadas?lat=${latitude}&lng=${longitude}`,
|
||||
{ headers: { 'Authorization': `Bearer ${token}` } }
|
||||
);
|
||||
const data = await res.json();
|
||||
if (data.cobertura) {
|
||||
setColoniaSeleccionada(data.colonia_sugerida);
|
||||
Alert.alert(
|
||||
'📍 Ubicación detectada',
|
||||
`Se detectó tu zona: ${data.colonia_sugerida}\nRuta: ${data.nombre_ruta}\nDistancia: ${data.distancia_metros}m`
|
||||
);
|
||||
} else {
|
||||
Alert.alert('Sin cobertura', 'Tu ubicación no está dentro de las zonas de servicio de Celaya');
|
||||
}
|
||||
} catch {
|
||||
Alert.alert('Error', 'No se pudo obtener tu ubicación');
|
||||
}
|
||||
setLocalizando(false);
|
||||
};
|
||||
|
||||
if (screen === 'splash') return (
|
||||
<View style={styles.splashContainer}>
|
||||
<Text style={styles.splashEmoji}>🚛</Text>
|
||||
@@ -319,6 +353,15 @@ export default function App() {
|
||||
value={direccion} onChangeText={setDireccion} />
|
||||
<TextInput style={styles.input} placeholder="Código postal (ej: 38000)"
|
||||
value={codigoPostal} onChangeText={setCodigoPostal} keyboardType="numeric" />
|
||||
<TouchableOpacity
|
||||
style={[styles.btnUbicacion, localizando && { opacity: 0.6 }]}
|
||||
onPress={usarUbicacion}
|
||||
disabled={localizando}>
|
||||
{localizando
|
||||
? <ActivityIndicator color="#1a7a4a" size="small" />
|
||||
: <Text style={styles.btnUbicacionText}>📡 Usar mi ubicación actual</Text>
|
||||
}
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={[styles.input, styles.combobox]}
|
||||
onPress={() => setMostrarColonias(!mostrarColonias)}>
|
||||
<Text style={{ color: coloniaSeleccionada ? '#1a1a1a' : '#999', fontSize: 15 }}>
|
||||
@@ -553,4 +596,6 @@ const styles = StyleSheet.create({
|
||||
alertaBox: { width: '100%', backgroundColor: '#fff3e0', borderRadius: 10, padding: 14, marginBottom: 16, borderWidth: 1, borderColor: '#ff9800' },
|
||||
alertaTitulo: { fontSize: 14, fontWeight: 'bold', color: '#e65100', marginBottom: 4 },
|
||||
alertaMensaje: { fontSize: 13, color: '#bf360c' },
|
||||
btnUbicacion: { width: '100%', borderRadius: 10, padding: 14, alignItems: 'center', marginBottom: 12, borderWidth: 1.5, borderColor: '#1a7a4a', borderStyle: 'dashed', backgroundColor: '#e8f5ee' },
|
||||
btnUbicacionText: { color: '#1a7a4a', fontWeight: '500', fontSize: 14 },
|
||||
});
|
||||
Reference in New Issue
Block a user