App Description:
The AttendanceApp in React Native stores the user's location and status (IN/OUT) in AsyncStorage with the default status as OUT. On opening the app, the user sees a Check In button that triggers the Geolocation API (watchPosition or getCurrentPosition). An if-else statement checks if the user's current location is within a 1-meter radius of their saved location. If the user is within the radius, the AsyncStorage is updated to set the status as IN, and a Check Out page is displayed. Pressing the Check Out button updates the status as OUT, and the user cannot check in or out until the next day. If the user attempts to check in/out, a page displays "YOU ARE ALREADY CHECKED OUT".
App Detailed Description:
I am making an AttendanceApp
in React Native in which it is that a user is saved in AsyncStorage
with his location (Longitude, Latitude) and a status of "IN" or "OUT" and its by default "OUT". Now I wanna make it like this that when he opens the app he sees a button "Check In" and when he presses that button @react-native-community/geolocation
's Geolocation works (watchPosition
or getCurrentPosition
what ever is good) and there is if else
which will tell if the user's current location is in 1 meter radius to his defined location then it changes the AsyncStorage
:
Status: "IN"
then I want it to show a "Check Out" page and when user presses the check out button his status is marked
Status: "OUT"
and then till the next day he can't check in or check out only a simple page comes "YOU ARE ALREADY CHECKED OUT".
❌:
Here comes the main part, when I save the user with longitude and latitude of my location and then when I am on that exact place and match it with the current location again on the Check IN/OUT page it works !!BUT!! even when I am far from the defined location I saved, when I press the buttons of either Check IN/OUT it works even that the location is not same obviously. I need help in this.
Save User Function:
const [Name, setName] = useState('');
const [Age, setAge] = useState(0);
const [Depart, setDepart] = useState('');
const [DisplayLat, setDisplayLat] = useState(0);
const [DisplayLong, setDisplayLong] = useState(0);
const [StringDisplayLat, setStringDisplayLat] = useState('');
const [StringDisplayLong, setStringDisplayLong] = useState('');
useEffect(() => {
Geolocation.getCurrentPosition(info => {
setDisplayLat(info.coords.latitude);
setDisplayLong(info.coords.longitude);
setStringDisplayLong(info.coords.longitude.toString());
setStringDisplayLat(info.coords.latitude.toString());
});
}, []);
return (
<View style={styles.container}>
<Text>Save User</Text>
<TextInput placeholder="Name" onChangeText={setName} />
<TextInput placeholder="Age" onChangeText={setAge} />
<TextInput placeholder="Depart" onChangeText={setDepart} />
<TextInput
placeholder="Long"
keyboardType="numeric"
value={StringDisplayLong}
onChangeText={setStringDisplayLong}
/>
<TextInput
placeholder="Lat"
keyboardType="numeric"
value={StringDisplayLat}
onChangeText={setStringDisplayLat}
/>
<Button
title="Save"
onPress={() => {
AsyncStorage.setItem(
'user',
JSON.stringify({
name: Name,
age: Age,
depart: Depart,
longitude: Number(StringDisplayLong),
latitude: Number(StringDisplayLat),
}),
);
}}
/>
<Text>Current Location</Text>
<Text>Latitude: {DisplayLat}</Text>
<Text>Longitude: {DisplayLong}</Text>
</View>
);
};
Check In Function:
const distance = 1;
const checkIn = () => {
console.log('Check In');
id = Geolocation.watchPosition(
position => {
if (
position.coords.latitude + distance >= User.latitude &&
position.coords.latitude - distance <= User.latitude &&
position.coords.longitude + distance >= User.longitude &&
position.coords.longitude - distance <= User.longitude
) {
setCurrentLoc({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
});
setMessage('Matched');
console.log('working');
setStatus('In');
AsyncStorage.setItem(
'@status',
JSON.stringify({status: 'In', date: new Date()}),
);
} else {
setMessage('NotMatched');
console.log('not working');
}
},
error => {
console.error(error);
},
{
enableHighAccuracy: false,
},
);
};
Check Out Function:
const checkOut = () => {
AsyncStorage.getItem('@status').then(status => {
if (status) {
AsyncStorage.setItem(
'@UserLog',
JSON.stringify({
name: User.name,
INstatus: JSON.parse(status).status,
INdate: JSON.parse(status).date,
OUTstatus: 'Out',
OUTdate: new Date(),
}),
);
}
});
setStatus('AlreadyOut');
AsyncStorage.setItem(
'@status',
JSON.stringify({status: 'AlreadyOut', date: new Date()}),
);
Geolocation.stopObserving(id);
Alert.alert('Check Out', 'You are checked out');
};
Check IN/OUT Buttons:
useEffect(() => {
AsyncStorage.getItem('user').then(user => {
if (user) {
setUser(JSON.parse(user));
}
});
AsyncStorage.getItem('@status').then(status => {
if (status) {
setStatus(JSON.parse(status).status);
if (JSON.parse(status).date !== new Date()) {
AsyncStorage.setItem(
'@status',
JSON.stringify({status: 'AlreadyOut', date: new Date()}),
);
setStatus('AlreadyOut');
} else {
AsyncStorage.setItem(
'@status',
JSON.stringify({status: 'Out', date: new Date()}),
);
setStatus('Out');
}
}
});
Geolocation.getCurrentPosition(
position => {
if (
position.coords.latitude + distance >= User.latitude &&
position.coords.latitude - distance <= User.latitude &&
position.coords.longitude + distance >= User.longitude &&
position.coords.longitude - distance <= User.longitude
) {
setCurrentLoc({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
});
console.log('Matched');
} else {
setCurrentLoc({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
});
console.log('NotMatched');
}
},
error => {
console.error(error);
},
{
enableHighAccuracy: false,
},
);
}, []);
return (
<View style={styles.container}>
{status === 'AlreadyOut' ? (
<View
style={{
height: Dimensions.get('screen').height,
justifyContent: 'center',
alignItems: 'center',
}}>
<Text>You are already checked out</Text>
<Button
title="Clear"
onPress={() => {
AsyncStorage.clear();
}}
/>
</View>
) : null}
{status === 'Out' ? (
<TouchableOpacity
onPress={checkIn}
style={{
height: Dimensions.get('screen').height / 4,
borderRadius: 30,
margin: 30,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'green',
}}>
<Text>Check In</Text>
</TouchableOpacity>
) : (
<TouchableOpacity
onPress={checkOut}
style={{
height: Dimensions.get('screen').height / 4,
borderRadius: 30,
margin: 30,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'tomato',
}}>
<Text>Check Out</Text>
</TouchableOpacity>
)}
{Message === 'Matched' ? (
<View
style={{
height: Dimensions.get('screen').height / 4,
borderRadius: 30,
margin: 30,
justifyContent: 'center',
alignItems: 'center',
}}>
<Text style={{fontSize: 20}}> ✅</Text>
<Text style={{fontSize: 15}}> ! ✅</Text>
</View>
) : null}
{Message === 'NotMatched' ? (
<View
style={{
height: Dimensions.get('screen').height / 4,
borderRadius: 30,
margin: 30,
justifyContent: 'center',
alignItems: 'center',
}}>
<Text style={{fontSize: 20}}> ❌</Text>
<Text style={{fontSize: 15}}> ! ❌</Text>
</View>
) : null}
<Button
title="Clear"
onPress={() => {
AsyncStorage.clear();
}}
/>
<Text>Latitude: {CurrentLoc.latitude}</Text>
<Text>Longitude: {CurrentLoc.longitude}</Text>
<Text>User Latitude: {User.latitude}</Text>
<Text>User Longitude: {User.longitude}</Text>
</View>
);