import React, { useState } from 'react'; import { Alert, Pressable, StyleSheet, Text, View, } from 'react-native'; import { NativeStackScreenProps } from '@react-navigation/native-stack'; import { Icon } from '../../../components/Icon'; import LinearGradient from 'react-native-linear-gradient'; import { BottomSheet, Button, Card, Input, ScreenShell } from '../../../components'; import { useAccounts } from '../hooks/useAccounts'; import type { HomeStackParamList } from '../../../navigation/types'; import { useTheme, fontFamily } from '../../../theme'; type Props = NativeStackScreenProps; type IconName = React.ComponentProps['name']; type ChangeField = 'name' | 'mobile' | 'email' | 'address'; type ChangeOption = { id: ChangeField; label: string; icon: IconName; }; const CHANGE_OPTIONS: ChangeOption[] = [ { id: 'name', label: 'Name', icon: 'person-outline' }, { id: 'mobile', label: 'Mobile', icon: 'call-outline' }, { id: 'email', label: 'Email', icon: 'mail-outline' }, { id: 'address', label: 'Address', icon: 'location-outline' }, ]; const STEPS = [ 'Enter your Aadhaar number', 'Upload documents & latest photograph', 'Accept the self-declaration and submit', ]; type DocOption = { id: string; label: string; hint: string; icon: IconName }; const DOCUMENT_OPTIONS: DocOption[] = [ { id: 'identity', label: 'Identity proof', hint: 'Aadhaar / Passport / Voter ID', icon: 'id-card-outline' }, { id: 'address', label: 'Address proof', hint: 'Utility bill / Rent agreement', icon: 'home-outline' }, { id: 'pan', label: 'PAN card', hint: 'Required for tax records', icon: 'card-outline' }, ]; const DECLARATIONS = [ 'The information and documents provided are true and correct.', 'I will inform the bank of any future change in my KYC details.', 'I consent to the bank verifying my documents with the issuing authority.', ]; const formatAadhaar = (value: string) => value .replace(/\D/g, '') .slice(0, 12) .replace(/(\d{4})(?=\d)/g, '$1 '); const extractDigits = (value: string) => value.replace(/\D/g, ''); export default function ReKycScreen({ route, navigation }: Props) { const theme = useTheme(); // Read from the bank on mount; nothing about accounts is cached locally. // Re-KYC is raised against an operative account. const { operableAccounts: accounts } = useAccounts(); const account = accounts.find((item) => item.accountNumber === route.params?.accountNumber) ?? accounts[0]; const [aadhaarNumber, setAadhaarNumber] = useState(''); const [selectedFields, setSelectedFields] = useState([]); const [updatedName, setUpdatedName] = useState(''); const [updatedMobile, setUpdatedMobile] = useState(''); const [updatedEmail, setUpdatedEmail] = useState(''); const [updatedAddress, setUpdatedAddress] = useState(''); const [consentGiven, setConsentGiven] = useState(false); const [uploadedDocs, setUploadedDocs] = useState([]); const [photoUploaded, setPhotoUploaded] = useState(false); const [acceptedDeclarations, setAcceptedDeclarations] = useState([]); const [otpSheetVisible, setOtpSheetVisible] = useState(false); const [otpValue, setOtpValue] = useState(''); const toggleDocument = (id: string) => { setUploadedDocs((current) => current.includes(id) ? current.filter((item) => item !== id) : [...current, id], ); }; const toggleDeclaration = (index: number) => { setAcceptedDeclarations((current) => current.includes(index) ? current.filter((item) => item !== index) : [...current, index], ); }; const allDeclarationsAccepted = acceptedDeclarations.length === DECLARATIONS.length; if (!account) { return ( Account not found We could not start re-KYC because the selected account is unavailable. ); } const toggleField = (field: ChangeField) => { setSelectedFields((currentValue) => currentValue.includes(field) ? currentValue.filter((item) => item !== field) : [...currentValue, field], ); }; const handleAadhaarChange = (value: string) => { setAadhaarNumber(formatAadhaar(value)); }; const getMissingFieldLabel = () => { if (selectedFields.includes('name') && updatedName.trim().length === 0) { return 'updated name'; } if (selectedFields.includes('mobile') && extractDigits(updatedMobile).length !== 10) { return 'updated mobile number'; } if (selectedFields.includes('email') && !updatedEmail.includes('@')) { return 'updated email'; } if (selectedFields.includes('address') && updatedAddress.trim().length < 8) { return 'updated address'; } return null; }; const handleSubmit = () => { const aadhaarDigits = extractDigits(aadhaarNumber); if (aadhaarDigits.length !== 12) { Alert.alert('Invalid Aadhaar', 'Enter a valid 12-digit Aadhaar number to continue.'); return; } if (selectedFields.length === 0 && !consentGiven) { Alert.alert('Consent required', 'Please verify that there is no change on your Aadhaar details.'); return; } const missingFieldLabel = getMissingFieldLabel(); if (missingFieldLabel) { Alert.alert('Incomplete details', `Please enter a valid ${missingFieldLabel}.`); return; } if (!photoUploaded) { Alert.alert('Photograph required', 'Please upload your latest photograph to continue.'); return; } if (!allDeclarationsAccepted) { Alert.alert('Self declaration', 'Please accept all the self-declaration statements to continue.'); return; } setOtpSheetVisible(true); }; const handleVerifyOtpAndSubmit = () => { if (otpValue.length !== 6) { Alert.alert('Invalid OTP', 'Please enter a valid 6-digit OTP.'); return; } setOtpSheetVisible(false); setTimeout(() => { Alert.alert( 'Re-KYC submitted', 'Your Aadhaar-based re-KYC request has been sent for review. We will update your records after validation.', [ { text: 'Back to account', onPress: () => navigation.goBack(), }, ], ); }, 300); }; return ( Update KYC when your records change Use Aadhaar re-verification if your name, mobile, email, or address has changed. {STEPS.map((step, index) => ( {index + 1} {step} ))} Aadhaar details Enter the Aadhaar linked to your updated identity details } /> What changed? Choose the fields that need to be updated {CHANGE_OPTIONS.map((option) => { const isSelected = selectedFields.includes(option.id); return ( toggleField(option.id)} style={[ styles.changeChip, { backgroundColor: isSelected ? theme.tint(theme.colors.primary, 0.07) : theme.colors.surfaceMuted, borderColor: isSelected ? theme.tint(theme.colors.primary, 0.27) : theme.colors.cardBorder, }, ]} > {option.label} ); })} {selectedFields.length === 0 ? ( setConsentGiven((currentValue) => !currentValue)} style={[ styles.consentCard, { backgroundColor: theme.colors.surfaceMuted, borderColor: theme.colors.cardBorder }, ]} > I verify that there is no change on my Aadhaar details. ) : null} {selectedFields.includes('name') ? ( ) : null} {selectedFields.includes('mobile') ? ( ) : null} {selectedFields.includes('email') ? ( ) : null} {selectedFields.includes('address') ? ( ) : null} {/* Document upload */} Upload documents Attach the latest copies of your KYC documents {DOCUMENT_OPTIONS.map((doc) => { const isUploaded = uploadedDocs.includes(doc.id); return ( toggleDocument(doc.id)} style={[ styles.uploadRow, { backgroundColor: isUploaded ? theme.tint(theme.colors.success, 0.06) : theme.colors.surfaceMuted, borderColor: isUploaded ? theme.tint(theme.colors.success, 0.27) : theme.colors.cardBorder, }, ]} > {doc.label} {isUploaded ? 'Uploaded · tap to remove' : doc.hint} ); })} {/* Latest photograph */} Latest photograph Upload a clear, recent passport-style photo setPhotoUploaded((value) => !value)} style={[ styles.photoTile, { backgroundColor: photoUploaded ? theme.tint(theme.colors.success, 0.06) : theme.colors.surfaceMuted, borderColor: photoUploaded ? theme.tint(theme.colors.success, 0.27) : theme.colors.cardBorder, }, ]} > {photoUploaded ? 'Photograph uploaded' : 'Tap to capture / upload photo'} {/* Self declaration */} Self declaration Please read and accept all statements {DECLARATIONS.map((statement, index) => { const accepted = acceptedDeclarations.includes(index); return ( toggleDeclaration(index)} style={[ styles.consentCard, { backgroundColor: theme.colors.surfaceMuted, borderColor: theme.colors.cardBorder }, ]} > {statement} ); })} {/* Video KYC option */} Prefer a video call? Complete re-KYC over a secure video call (V-CIP)