Added a new authentication screen with PIN, Fingerprint, and Face ID options.

Improved UI design and usability using a clean keypad layout and Ionicons.
This commit is contained in:
mansi-dev
2026-01-09 22:59:19 +05:30
parent 967e70b72d
commit c8504e1ac1
3 changed files with 327 additions and 34 deletions

181
App.tsx
View File

@@ -1,45 +1,166 @@
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
*/
import { NewAppScreen } from '@react-native/new-app-screen';
import { StatusBar, StyleSheet, useColorScheme, View } from 'react-native';
import React, { useState } from 'react';
import {
SafeAreaProvider,
useSafeAreaInsets,
} from 'react-native-safe-area-context';
View,
Text,
StyleSheet,
TouchableOpacity,
SafeAreaView,
} from 'react-native';
import Ionicons from '@react-native-vector-icons/ionicons';
function App() {
const isDarkMode = useColorScheme() === 'dark';
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 (
<SafeAreaProvider>
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
<AppContent />
</SafeAreaProvider>
);
}
<SafeAreaView style={styles.container}>
<Text style={styles.title}>Verify Identity</Text>
<Text style={styles.subtitle}>
Use PIN, Fingerprint or Face ID
</Text>
function AppContent() {
const safeAreaInsets = useSafeAreaInsets();
return (
<View style={styles.container}>
<NewAppScreen
templateFileName="App.tsx"
safeAreaInsets={safeAreaInsets}
{/* 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;

171
package-lock.json generated
View File

@@ -8,6 +8,7 @@
"name": "authenticationsdk",
"version": "0.0.1",
"dependencies": {
"@react-native-vector-icons/ionicons": "^12.3.0",
"@react-native/new-app-screen": "0.83.1",
"react": "19.2.0",
"react-native": "0.83.1",
@@ -2924,6 +2925,132 @@
"node": ">=10"
}
},
"node_modules/@react-native-vector-icons/common": {
"version": "12.4.0",
"resolved": "https://registry.npmjs.org/@react-native-vector-icons/common/-/common-12.4.0.tgz",
"integrity": "sha512-t9W0q+AW7WH1Oj5aEg7wGNXDLZJb5sIVkAWo5qtad3PcbBADqoCdikRK/ToLK+xlB0TxjcuL0T74ogudMkYGeA==",
"license": "MIT",
"dependencies": {
"find-up": "^7.0.0",
"picocolors": "^1.1.1",
"plist": "^3.1.0"
},
"bin": {
"rnvi-update-plist": "lib/commonjs/scripts/updatePlist.js"
},
"engines": {
"node": ">=20.19.0 <21.0.0 || >=22.0.0"
},
"peerDependencies": {
"@react-native-vector-icons/get-image": "^12.3.0",
"react": "*",
"react-native": "*"
},
"peerDependenciesMeta": {
"@react-native-vector-icons/get-image": {
"optional": true
}
}
},
"node_modules/@react-native-vector-icons/common/node_modules/find-up": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz",
"integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==",
"license": "MIT",
"dependencies": {
"locate-path": "^7.2.0",
"path-exists": "^5.0.0",
"unicorn-magic": "^0.1.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@react-native-vector-icons/common/node_modules/locate-path": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz",
"integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==",
"license": "MIT",
"dependencies": {
"p-locate": "^6.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@react-native-vector-icons/common/node_modules/p-limit": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz",
"integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==",
"license": "MIT",
"dependencies": {
"yocto-queue": "^1.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@react-native-vector-icons/common/node_modules/p-locate": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz",
"integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==",
"license": "MIT",
"dependencies": {
"p-limit": "^4.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@react-native-vector-icons/common/node_modules/path-exists": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz",
"integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==",
"license": "MIT",
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
"node_modules/@react-native-vector-icons/common/node_modules/yocto-queue": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz",
"integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==",
"license": "MIT",
"engines": {
"node": ">=12.20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@react-native-vector-icons/ionicons": {
"version": "12.3.0",
"resolved": "https://registry.npmjs.org/@react-native-vector-icons/ionicons/-/ionicons-12.3.0.tgz",
"integrity": "sha512-H/rlYzUEm0hhwwca2k6VMNjy0rLcjan6iwyaYDXMhsJQl7O4+Qkm7uVd/KEreS5gXfGuntUlcSa9GSn+dYqnjA==",
"license": "MIT",
"dependencies": {
"@react-native-vector-icons/common": "^12.3.0"
},
"engines": {
"node": ">= 18.0.0"
},
"peerDependencies": {
"react": "*",
"react-native": "*"
}
},
"node_modules/@react-native/assets-registry": {
"version": "0.83.1",
"resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.83.1.tgz",
@@ -3753,6 +3880,15 @@
"devOptional": true,
"license": "MIT"
},
"node_modules/@xmldom/xmldom": {
"version": "0.8.11",
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.11.tgz",
"integrity": "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/abort-controller": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
@@ -9611,6 +9747,20 @@
"node": ">=8"
}
},
"node_modules/plist": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz",
"integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==",
"license": "MIT",
"dependencies": {
"@xmldom/xmldom": "^0.8.8",
"base64-js": "^1.5.1",
"xmlbuilder": "^15.1.1"
},
"engines": {
"node": ">=10.4.0"
}
},
"node_modules/possible-typed-array-names": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
@@ -11418,6 +11568,18 @@
"node": ">=4"
}
},
"node_modules/unicorn-magic": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz",
"integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
@@ -11716,6 +11878,15 @@
"async-limiter": "~1.0.0"
}
},
"node_modules/xmlbuilder": {
"version": "15.1.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
"integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==",
"license": "MIT",
"engines": {
"node": ">=8.0"
}
},
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",

View File

@@ -10,9 +10,10 @@
"test": "jest"
},
"dependencies": {
"@react-native-vector-icons/ionicons": "^12.3.0",
"@react-native/new-app-screen": "0.83.1",
"react": "19.2.0",
"react-native": "0.83.1",
"@react-native/new-app-screen": "0.83.1",
"react-native-safe-area-context": "^5.5.2"
},
"devDependencies": {