106 lines
2.5 KiB
TypeScript
106 lines
2.5 KiB
TypeScript
import React, { useEffect, useState } from 'react';
|
|
import {
|
|
View,
|
|
Text,
|
|
TextInput,
|
|
Button,
|
|
Alert,
|
|
StyleSheet,
|
|
} from 'react-native';
|
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
|
|
const PIN_KEY = 'USER_PIN';
|
|
|
|
const App: React.FC = () => {
|
|
const [pin, setPin] = useState<string>('');
|
|
const [savedPin, setSavedPin] = useState<string | null>(null);
|
|
const [loggedIn, setLoggedIn] = useState<boolean>(false);
|
|
|
|
useEffect(() => {
|
|
loadPin();
|
|
}, []);
|
|
|
|
const loadPin = async (): Promise<void> => {
|
|
const storedPin = await AsyncStorage.getItem(PIN_KEY);
|
|
setSavedPin(storedPin);
|
|
};
|
|
|
|
const setUserPin = async (): Promise<void> => {
|
|
if (pin.length !== 4) {
|
|
Alert.alert('PIN must be 4 digits');
|
|
return;
|
|
}
|
|
await AsyncStorage.setItem(PIN_KEY, pin);
|
|
setSavedPin(pin);
|
|
setPin('');
|
|
Alert.alert('PIN set successfully');
|
|
};
|
|
|
|
const loginWithPin = (): void => {
|
|
if (pin === savedPin) {
|
|
setLoggedIn(true);
|
|
setPin('');
|
|
} else {
|
|
Alert.alert('Incorrect PIN');
|
|
}
|
|
};
|
|
|
|
const logout = (): void => {
|
|
setLoggedIn(false);
|
|
};
|
|
|
|
if (loggedIn) {
|
|
return (
|
|
<View style={styles.container}>
|
|
<Text style={styles.title}>Hi Dude!</Text>
|
|
<Button title="Logout" onPress={logout} />
|
|
</View>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<View style={styles.container}>
|
|
<Text style={styles.title}>
|
|
{savedPin ? 'Enter PIN' : 'Set PIN'}
|
|
</Text>
|
|
|
|
<TextInput
|
|
style={styles.input}
|
|
keyboardType="numeric"
|
|
secureTextEntry
|
|
maxLength={4}
|
|
value={pin}
|
|
onChangeText={setPin}
|
|
placeholder="Enter 4-digit PIN"
|
|
/>
|
|
|
|
<Button
|
|
title={savedPin ? 'Login' : 'Save PIN'}
|
|
onPress={savedPin ? loginWithPin : setUserPin}
|
|
/>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
export default App;
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
justifyContent: 'center',
|
|
padding: 20,
|
|
},
|
|
title: {
|
|
fontSize: 22,
|
|
marginBottom: 20,
|
|
textAlign: 'center',
|
|
},
|
|
input: {
|
|
borderWidth: 1,
|
|
padding: 12,
|
|
marginBottom: 20,
|
|
borderRadius: 5,
|
|
fontSize: 18,
|
|
textAlign: 'center',
|
|
},
|
|
}); |