import { View, Text, StyleSheet, TouchableOpacity, ActivityIndicator } from 'react-native' import { useState, useEffect } from 'react' import { LinearGradient } from 'expo-linear-gradient' import { Ionicons } from '@expo/vector-icons' import * as Location from 'expo-location' import { theme } from '../styles/theme' import { isWithinGeofence, calculateDistance, getFormattedDistance, GYM_LOCATION } from '../services/geofencing' export interface GeofenceStatusProps { onStatusChange?: (isInside: boolean) => void } export const GeofenceStatus = ({ onStatusChange }: GeofenceStatusProps) => { const [loading, setLoading] = useState(false) const [isInside, setIsInside] = useState(false) const [distance, setDistance] = useState('--') const [permission, setPermission] = useState('undetermined') const [lastCheck, setLastCheck] = useState(null) const checkGeofence = async () => { try { setLoading(true) // Request location permission const { status } = await Location.requestForegroundPermissionsAsync() setPermission(status) if (status !== 'granted') { setLoading(false) return } // Get current location const location = await Location.getCurrentPositionAsync({ accuracy: Location.Accuracy.Balanced, }) const { latitude, longitude } = location.coords // Check if within geofence const within = isWithinGeofence(latitude, longitude, 500) setIsInside(within) onStatusChange?.(within) // Calculate distance const dist = calculateDistance( latitude, longitude, GYM_LOCATION.latitude, GYM_LOCATION.longitude ) setDistance(getFormattedDistance(dist)) setLastCheck(new Date()) } catch (error) { console.error('Geofence check error:', error) } finally { setLoading(false) } } useEffect(() => { checkGeofence() // Auto-check every 30 seconds const interval = setInterval(checkGeofence, 30000) return () => clearInterval(interval) }, []) return ( {isInside ? 'At Gym' : 'Away from Gym'} {loading ? ( ) : ( )} Distance {distance} {lastCheck && ( Last check: {lastCheck.toLocaleTimeString()} )} {permission !== 'granted' && ( Location permission required )} ) } const styles = StyleSheet.create({ container: { paddingHorizontal: 16, paddingVertical: 12, }, card: { borderRadius: 16, padding: 16, overflow: 'hidden', }, header: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12, }, titleRow: { flexDirection: 'row', alignItems: 'center', gap: 12, }, title: { fontSize: 18, fontWeight: '600', color: '#fff', }, refreshButton: { padding: 8, borderRadius: 8, backgroundColor: 'rgba(255, 255, 255, 0.2)', }, content: { gap: 12, }, stat: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', }, statLabel: { fontSize: 14, color: 'rgba(255, 255, 255, 0.8)', fontWeight: '500', }, statValue: { fontSize: 16, fontWeight: '600', color: '#fff', }, lastCheck: { fontSize: 12, color: 'rgba(255, 255, 255, 0.7)', marginTop: 4, }, permissionAlert: { flexDirection: 'row', alignItems: 'center', gap: 8, marginTop: 12, paddingTop: 12, borderTopWidth: 1, borderTopColor: 'rgba(255, 255, 255, 0.3)', }, permissionText: { fontSize: 12, color: '#fff', fontWeight: '500', }, })