167 lines
4.4 KiB
TypeScript
167 lines
4.4 KiB
TypeScript
import React, { useState } from 'react';
|
|
import {
|
|
View,
|
|
Text,
|
|
StyleSheet,
|
|
TouchableOpacity,
|
|
SafeAreaView,
|
|
} from 'react-native';
|
|
import Ionicons from '@react-native-vector-icons/ionicons';
|
|
|
|
const PIN_LENGTH = 4;
|
|
|
|
const App: React.FC = () => {
|
|
const [pin, setPin] = useState('');
|
|
|
|
const handlePress = (value: string) => {
|
|
if (pin.length < PIN_LENGTH) {
|
|
setPin(pin + value);
|
|
}
|
|
};
|
|
|
|
const handleDelete = () => {
|
|
setPin(pin.slice(0, -1));
|
|
};
|
|
|
|
return (
|
|
<SafeAreaView style={styles.container}>
|
|
<Text style={styles.title}>Verify Identity</Text>
|
|
<Text style={styles.subtitle}>
|
|
Use PIN, Fingerprint or Face ID
|
|
</Text>
|
|
|
|
{/* PIN DOTS */}
|
|
<View style={styles.pinRow}>
|
|
{Array.from({ length: PIN_LENGTH }).map((_, i) => (
|
|
<View
|
|
key={i}
|
|
style={[
|
|
styles.pinDot,
|
|
pin.length > i && styles.pinDotFilled,
|
|
]}
|
|
/>
|
|
))}
|
|
</View>
|
|
|
|
{/* BIOMETRIC OPTIONS */}
|
|
<View style={styles.bioRow}>
|
|
<TouchableOpacity style={styles.bioBtn}>
|
|
<Ionicons name="finger-print" size={36} color="#2563EB" />
|
|
<Text style={styles.bioText}>Fingerprint</Text>
|
|
</TouchableOpacity>
|
|
|
|
<TouchableOpacity style={styles.bioBtn}>
|
|
<Ionicons name="happy-outline" size={36} color="#2563EB" />
|
|
<Text style={styles.bioText}>Face ID</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
|
|
{/* KEYPAD */}
|
|
<View style={styles.keypad}>
|
|
{[1, 2, 3, 4, 5, 6, 7, 8, 9, '', 0, 'del'].map((item, index) => {
|
|
if (item === '') {
|
|
return <View key={index} style={styles.key} />;
|
|
}
|
|
|
|
if (item === 'del') {
|
|
return (
|
|
<TouchableOpacity
|
|
key={index}
|
|
style={styles.key}
|
|
onPress={handleDelete}
|
|
>
|
|
<Ionicons
|
|
name="backspace-outline"
|
|
size={26}
|
|
color="#333"
|
|
/>
|
|
</TouchableOpacity>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<TouchableOpacity
|
|
key={index}
|
|
style={styles.key}
|
|
onPress={() => handlePress(item.toString())}
|
|
>
|
|
<Text style={styles.keyText}>{item}</Text>
|
|
</TouchableOpacity>
|
|
);
|
|
})}
|
|
</View>
|
|
</SafeAreaView>
|
|
);
|
|
|
|
};
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
backgroundColor: '#F8FAFF',
|
|
alignItems: 'center',
|
|
paddingHorizontal: 20,
|
|
},
|
|
title: {
|
|
fontSize: 24,
|
|
fontWeight: '700',
|
|
marginTop: 40,
|
|
color: '#111827',
|
|
},
|
|
subtitle: {
|
|
fontSize: 14,
|
|
color: '#6B7280',
|
|
marginTop: 6,
|
|
},
|
|
|
|
pinRow: {
|
|
flexDirection: 'row',
|
|
marginVertical: 28,
|
|
},
|
|
pinDot: {
|
|
width: 14,
|
|
height: 14,
|
|
borderRadius: 7,
|
|
borderWidth: 1.5,
|
|
borderColor: '#2563EB',
|
|
marginHorizontal: 8,
|
|
},
|
|
pinDotFilled: {
|
|
backgroundColor: '#2563EB',
|
|
},
|
|
|
|
bioRow: {
|
|
flexDirection: 'row',
|
|
marginBottom: 30,
|
|
},
|
|
bioBtn: {
|
|
alignItems: 'center',
|
|
marginHorizontal: 30,
|
|
},
|
|
bioText: {
|
|
marginTop: 6,
|
|
fontSize: 12,
|
|
color: '#374151',
|
|
},
|
|
|
|
keypad: {
|
|
width: '80%',
|
|
flexDirection: 'row',
|
|
flexWrap: 'wrap',
|
|
justifyContent: 'center',
|
|
},
|
|
key: {
|
|
width: '33%',
|
|
height: 70,
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
},
|
|
keyText: {
|
|
fontSize: 26,
|
|
fontWeight: '500',
|
|
color: '#111827',
|
|
},
|
|
});
|
|
|
|
|
|
export default App;
|