Update VerificationScreen to use react-native-confirmation-code-field for enhanced OTP input; add bundleIdentifier in app.json and include new dependency in package.json and package-lock.json.

This commit is contained in:
2025-09-11 15:37:38 +05:00
parent a41851dfcc
commit 99bdb01644
4 changed files with 75 additions and 21 deletions

View File

@@ -16,7 +16,8 @@
"supportsTablet": true,
"statusBar": {
"barStyle": "dark-content"
}
},
"bundleIdentifier": "com.nurmuhammet.ali.tbbankonline"
},
"android": {
"adaptiveIcon": {

18
package-lock.json generated
View File

@@ -23,6 +23,7 @@
"expo-system-ui": "~5.0.11",
"react": "19.0.0",
"react-native": "0.79.5",
"react-native-confirmation-code-field": "^8.0.1",
"react-native-gesture-handler": "~2.24.0",
"react-native-modal-datetime-picker": "^15.0.1",
"react-native-safe-area-context": "5.4.0",
@@ -6733,6 +6734,23 @@
}
}
},
"node_modules/react-native-confirmation-code-field": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/react-native-confirmation-code-field/-/react-native-confirmation-code-field-8.0.1.tgz",
"integrity": "sha512-pwrhQtspFEp0y/gxZRp8hrra+UjAYfwAsW5Sn3yYtdUZVyRjAZPBnUb3rOc+z5L5o2ml03z5P3uvTK0yQwXsmA==",
"peerDependencies": {
"react": ">=16.4.0",
"react-native": ">=0.64.0"
},
"peerDependenciesMeta": {
"react": {
"optional": true
},
"react-native": {
"optional": true
}
}
},
"node_modules/react-native-edge-to-edge": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/react-native-edge-to-edge/-/react-native-edge-to-edge-1.6.0.tgz",

View File

@@ -21,15 +21,16 @@
"expo-image-picker": "~16.1.4",
"expo-splash-screen": "^31.0.8",
"expo-status-bar": "~2.2.3",
"expo-system-ui": "~5.0.11",
"react": "19.0.0",
"react-native": "0.79.5",
"react-native-confirmation-code-field": "^8.0.1",
"react-native-gesture-handler": "~2.24.0",
"react-native-modal-datetime-picker": "^15.0.1",
"react-native-safe-area-context": "5.4.0",
"react-native-screens": "^4.11.1",
"react-native-svg": "15.11.2",
"react-native-webview": "13.13.5",
"expo-system-ui": "~5.0.11"
"react-native-webview": "13.13.5"
},
"devDependencies": {
"@babel/core": "^7.20.0"

View File

@@ -16,15 +16,27 @@ import { StatusBar } from 'expo-status-bar';
import { useFocusEffect } from '@react-navigation/native';
import { useAuth } from '../../contexts/AuthContext';
import Button from '../../components/Button';
import Input from '../../components/Input';
import {
CodeField,
Cursor,
useBlurOnFulfill,
useClearByFocusCell,
} from 'react-native-confirmation-code-field';
import { COLORS } from '../../constants/colors';
const CELL_COUNT = 6;
const VerificationScreen = ({ navigation }) => {
const [code, setCode] = useState('');
const [countdown, setCountdown] = useState(60);
const [canResend, setCanResend] = useState(false);
const { verify, isLoading, pendingVerification, clearPendingVerification } = useAuth();
const countdownRef = useRef(null);
const ref = useBlurOnFulfill({ value: code, cellCount: CELL_COUNT });
const [props, getCellOnLayoutHandler] = useClearByFocusCell({
value: code,
setValue: setCode,
});
useEffect(() => {
if (!pendingVerification) {
@@ -74,18 +86,18 @@ const VerificationScreen = ({ navigation }) => {
}, 1000);
};
const handleVerify = async () => {
if (!code.trim()) {
const handleVerify = async (filledCode) => {
if (!filledCode.trim()) {
Alert.alert('Ýalňyşlyk', 'Tassyklama koduny giriziň');
return;
}
if (!/^\d{6}$/.test(code.trim())) {
if (!/^\d{6}$/.test(filledCode.trim())) {
Alert.alert('Ýalňyşlyk', 'Tassyklama kody 6 sanly bolmaly');
return;
}
const result = await verify(code.trim());
const result = await verify(filledCode.trim());
if (result.success) {
// Navigation will be handled by AuthContext
@@ -94,6 +106,8 @@ const VerificationScreen = ({ navigation }) => {
}
};
const handleVerifyWrapper = () => handleVerify(code);
const handleResendCode = async () => {
if (!canResend) return;
@@ -153,24 +167,29 @@ const VerificationScreen = ({ navigation }) => {
</View>
<View style={styles.formContainer}>
<Input
label="Tassyklama kody"
<CodeField
ref={ref}
{...props}
value={code}
onChangeText={setCode}
placeholder="123456"
keyboardType="numeric"
maxLength={6}
style={styles.codeInput}
textAlign="center"
returnKeyType="done"
onSubmitEditing={handleVerify}
cellCount={CELL_COUNT}
rootStyle={styles.otpContainer}
keyboardType="number-pad"
textContentType="oneTimeCode"
autoComplete="sms-otp"
renderCell={({ index, symbol, isFocused }) => (
<Text
key={index}
style={[styles.otpInput, isFocused && styles.otpInputHighlight]}
onLayout={getCellOnLayoutHandler(index)}>
{symbol || (isFocused ? <Cursor/> : null)}
</Text>
)}
onSubmitEditing={handleVerifyWrapper}
/>
<Button
title="Tassykla"
onPress={handleVerify}
onPress={handleVerifyWrapper}
loading={isLoading}
style={styles.verifyButton}
/>
@@ -259,10 +278,25 @@ const styles = StyleSheet.create({
formContainer: {
alignItems: 'center',
},
codeInput: {
width: '100%',
otpContainer: {
width: '90%',
marginBottom: 32,
},
otpInput: {
width: 45,
height: 60,
lineHeight: 58,
borderWidth: 1,
borderRadius: 12,
borderColor: COLORS.gray[300],
color: COLORS.textPrimary,
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
},
otpInputHighlight: {
borderColor: COLORS.primary,
},
verifyButton: {
width: '100%',
marginBottom: 32,