So what i am trying to do is that I am doing conditional rendering of my AccountStack and AuthStack on my AccountTab, now my AuthStack contains screens Welcome, Login and Otp and after entering the otp i want to navigate back to the Account Screen which is in my AccountStack but I am not getting navigated to Account screen instead I am getting stuck on Opt screen. it seems like my checkIfLoggedIn function is not getting called after successful login.
I want to know what I am doing wrong in my Code
Here are my BottomTabNavigator, AccountStack and AuthStack, Welcome, Login and Otp screen
const BottomNavigator = () => {
const BottomTab = createBottomTabNavigator()
// const isFocused = useIsFocused();
const [isFocused, setIsFocused] = useState(true)
const navigation = useNavigation()
const [isLoggedIn, setIsLoggedIn] = useState(false)
useFocusEffect(() => {
const onScreenFocus = () => {
setIsFocused(true)
}
navigation.addListener('focus', onScreenFocus)
return () => {
navigation.removeListener('focus', onScreenFocus)
}
})
useEffect(() => {
checkIfLoggedIn()
}, [])
const checkIfLoggedIn = async () => {
try {
const value = await AsyncStorage.getItem('isLoggedIn')
console.log('value from bottomtab', value)
if (value !== null) {
setIsLoggedIn(true)
}
} catch (error) {
// Error retrieving data
console.log(error)
}
}
console.log('isLoggedI from bottomtab', isLoggedIn)
const AccountScreenComponent = isLoggedIn ? AccountNavigator : AuthNavigator;
return (
<BottomTab.Navigator
backBehavior='history'
screenOptions={{
headerShown: false,
tabBarActiveTintColor: colors.secondary,
tabBarInactiveTintColor: colors.primary,
unmountOnBlur: true,
tabBarOnPress: ({navigation, defaultHandler}) => {
if (isFocused) {
navigation.popToTop()
} else {
defaultHandler()
}
},
tabBarStyle: {
backgroundColor: colors.background,
borderTopWidth: ResponsivePixels.size1,
borderTopColor: colors.divider2,
alignItems: 'center',
justifyContent: 'center',
height: ResponsivePixels.size42,
paddingHorizontal: ResponsivePixels.size10,
},
tabBarItemStyle: {
height: ResponsivePixels.size50,
alignItems: 'center',
},
tabBarLabelStyle: {
fontSize: ResponsivePixels.size10,
fontFamily: 'Sarabun-SemiBold',
// lineHeight: ResponsivePixels.size14,
},
tabBarIconStyle: {
marginVertical: ResponsivePixels.size2,
},
}}>
<BottomTab.Screen
name={'Home'}
component={HomeNavigator}
options={{
title: '',
tabBarIcon: ({focused}) => {
if (focused) {
return (
<View
style={{
borderWidth: ResponsivePixels.size1,
paddingHorizontal: ResponsivePixels.size5,
paddingVertical: ResponsivePixels.size4,
borderRadius: ResponsivePixels.size12,
borderColor: colors.secondaryContainer,
backgroundColor: colors.secondaryContainer,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
marginTop: ResponsivePixels.size8,
}}>
<Image
source={bottomHomeActvieIcon}
style={{
width: ResponsivePixels.size25,
height: ResponsivePixels.size25,
}}
/>
<Text
style={{
marginLeft: ResponsivePixels.size3,
fontSize: ResponsivePixels.size12,
fontFamily: 'Sarabun-SemiBold',
color: colors.secondary,
}}>
Home
</Text>
</View>
)
} else {
return (
<Image
source={bottomHomeIcon}
style={{
width: ResponsivePixels.size25,
height: ResponsivePixels.size25,
marginTop: ResponsivePixels.size8,
}}
/>
)
}
},
}}
/>
<BottomTab.Screen
name={'Search'}
component={SearchNavigator}
options={{
title: '',
tabBarIcon: ({focused}) => (
<Image
source={focused ? bottomSearchIcon : bottomSearchIcon}
style={{
width: ResponsivePixels.size25,
height: ResponsivePixels.size25,
marginTop: ResponsivePixels.size8,
}}
/>
),
}}
/>
<BottomTab.Screen
name={'Order'}
component={OrderNavigator}
options={{
title: '',
tabBarIcon: ({focused}) => {
if (focused) {
return (
<View
style={{
borderWidth: ResponsivePixels.size1,
paddingHorizontal: ResponsivePixels.size5,
paddingVertical: ResponsivePixels.size4,
borderRadius: ResponsivePixels.size12,
borderColor: colors.secondaryContainer,
backgroundColor: colors.secondaryContainer,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
marginTop: ResponsivePixels.size8,
}}>
<Image
source={bottomOrderActiveIcon}
style={{
width: ResponsivePixels.size25,
height: ResponsivePixels.size25,
}}
/>
<Text
style={{
marginLeft: ResponsivePixels.size3,
fontSize: ResponsivePixels.size12,
fontFamily: 'Sarabun-SemiBold',
color: colors.secondary,
}}>
Order
</Text>
</View>
)
} else {
return (
<Image
source={bottomOrderIcon}
style={{
width: ResponsivePixels.size25,
height: ResponsivePixels.size25,
marginTop: ResponsivePixels.size8,
}}
/>
)
}
},
}}
/>
<BottomTab.Screen
name={'Basket'}
component={BasketNavigator}
options={{
title: '',
tabBarIcon: ({focused}) => {
if (focused) {
return (
<View
style={{
borderWidth: ResponsivePixels.size1,
paddingHorizontal: ResponsivePixels.size5,
paddingVertical: ResponsivePixels.size4,
borderRadius: ResponsivePixels.size12,
borderColor: colors.secondaryContainer,
backgroundColor: colors.secondaryContainer,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
marginTop: ResponsivePixels.size8,
}}>
<Image
source={bottomBasketActiveIcon}
style={{
width: ResponsivePixels.size25,
height: ResponsivePixels.size25,
}}
/>
<Text
style={{
marginLeft: ResponsivePixels.size3,
fontSize: ResponsivePixels.size12,
fontFamily: 'Sarabun-SemiBold',
color: colors.secondary,
}}>
Basket
</Text>
</View>
)
} else {
return (
<Image
source={bottomBasketIcon}
style={{
width: ResponsivePixels.size25,
height: ResponsivePixels.size25,
marginTop: ResponsivePixels.size8,
}}
/>
)
}
},
}}
/>
<BottomTab.Screen
name={'Account'}
component={AccountScreenComponent}
initialParams={{fromBasketScreen: false}}
options={{
title: '',
tabBarIcon: ({focused}) => {
if (focused) {
return (
<View
style={{
borderWidth: ResponsivePixels.size1,
paddingHorizontal: ResponsivePixels.size5,
paddingVertical: ResponsivePixels.size4,
borderRadius: ResponsivePixels.size12,
borderColor: colors.secondaryContainer,
backgroundColor: colors.secondaryContainer,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
marginTop: ResponsivePixels.size8,
}}>
<Image
source={bottomAccountActiveIcon}
style={{
width: ResponsivePixels.size25,
height: ResponsivePixels.size25,
}}
/>
<Text
style={{
marginLeft: ResponsivePixels.size3,
fontSize: ResponsivePixels.size12,
fontFamily: 'Sarabun-SemiBold',
color: colors.secondary,
}}>
{isLoggedIn ? 'Account' : 'Login'}
</Text>
</View>
)
} else {
return (
<Image
source={bottomAccountIcon}
style={{
width: ResponsivePixels.size25,
height: ResponsivePixels.size25,
marginTop: ResponsivePixels.size8,
}}
/>
)
}
},
}}
/>
</BottomTab.Navigator>
)
}
export default BottomNavigator
const AccountNavigator = () => {
const AccountStack = createStackNavigator()
return (
<AccountStack.Navigator initialRouteName={ACCOUNT} screenOptions={{headerShown: false}}>
<AccountStack.Screen name={ACCOUNT} component={Account} />
<AccountStack.Screen name={PROFILE} component={Profile} />
<AccountStack.Screen name={MY_ADDRESS} component={MyAddressess} />
<AccountStack.Screen name={ADD_ADDRESS} component={AddNewAddress} />
<AccountStack.Screen name={MY_SHOPPINGLIST} component={ShoppingList} />
<AccountStack.Screen name={HELP_CENTER} component={HelpCenter} />
<AccountStack.Screen name={ORDER_SUCCESSFUL} component={OrderPlaced} />
<AccountStack.Screen name={FAQ} component={Faqs} />
</AccountStack.Navigator>
)
}
export default AccountNavigator;
const AuthNavigator = () => {
const AuthStack = createNativeStackNavigator();
return (
<AuthStack.Navigator screenOptions={{headerShown:false}}>
<AuthStack.Screen name={WELCOME} component={Welcome} initialParams={{ fromBasketScreen: false }} />
<AuthStack.Screen name={LOGIN} component={Login} />
<AuthStack.Screen name={OTP} component={OtpScreen}/>
</AuthStack.Navigator>
);
};
export default AuthNavigator;
const Welcome = ({onChangedText, value, loading, onSubmit}) => {
const navigation = useNavigation()
const route = useRoute()
useEffect(() => {
navigation.getParent()?.setOptions({
tabBarStyle: {
display: 'none',
},
})
return () =>
navigation.getParent()?.setOptions({
tabBarStyle: undefined,
})
}, [navigation])
const handleLogin = () => {
navigation.navigate(LOGIN, {
fromBasketScreen: route.params?.fromBasketScreen,
})
console.log('fromBasketScreen welcome', route.params?.fromBasketScreen)
}
return (
<ImageBackground source={welcomeImage} style={{flex: 1}}>
<StatusBar
translucent
backgroundColor='transparent'
barStyle={'dark-content'}
/>
<View style={styles.loginWrapper}>
<View style={styles.welcomeLabel}>
<Text style={styles.welcomeLabel}>Welcome to</Text>
<Text style={styles.logoLabel}>NNT Mart</Text>
<View style={styles.cardContainer}>
<Text style={styles.mobileText}>Enter your{'\n'}mobile number</Text>
<View style={styles.textInputContainer}>
<Image style={{marginStart: 12}} source={flagIcon} />
<Text
style={{
fontFamily: 'Sarabun-Regular',
marginLeft: ResponsivePixels.size12,
color: colors.onTextMedium,
}}>
+ 91
</Text>
<TextInput
placeholder='00000 00000'
value={value}
style={styles.textInput}
keyboardType='phone-pad'
onPressIn={handleLogin}
/>
</View>
</View>
<TouchableOpacity
style={styles.cbWrapper}
onPress={() => navigation.navigate('Home', {screen: HOME})}>
<Text
style={{
color: colors.primary,
paddingLeft: loading ? ResponsivePixels.size5 : 0,
fontFamily: 'Prompt-Medium',
fontSize: ResponsivePixels.size14,
}}>
Continue as guest
</Text>
</TouchableOpacity>
</View>
</View>
</ImageBackground>
)
}
export default Welcome
const Login = () => {
const route = useRoute()
const navigation = useNavigation()
const [mobileNumber, setMobileNumber] = useState('')
const [isValueValid, setIsValueValid] = useState(false)
const dispatch = useDispatch()
const [isLoading, setIsLoading] = useState(false)
const handleInputChange = inputValue => {
setMobileNumber(inputValue)
if (inputValue.length === 10 && /^\d+$/.test(inputValue)) {
setIsValueValid(true)
} else {
setIsValueValid(false)
}
}
const handleContinue = () => {
console.log('Navigating to OTP screen');
setIsLoading(true)
dispatch(postLogin(mobileNumber))
.then(result => {
console.log('result', result)
if (!result.error) {
navigation.navigate(OTP, {
fromBasketScreen: route.params?.fromBasketScreen,
})
console.log(
'fromBasketScreen login',
route.params?.fromBasketScreen,
)
} else {
console.log(result.error)
}
})
.catch(error => {
console.log('error===>>>', error)
})
.finally(() => {
setIsLoading(false)
})
}
const [isFocused, setIsFocused] = useState(false)
const handleFocus = () => {
setIsFocused(true)
}
const handleBlur = () => {
setIsFocused(false)
}
return (
<View style={styles.welcomeContentContainer}>
<Header leftIcon='back' />
<Text style={styles.welcomeTextHeader}>
Enter your{'\n'}mobile number
</Text>
<Text style={styles.welcomeText}>We will send you a OTP code</Text>
<View
style={[
styles.loginInputContainer,
isFocused && styles.loginInputContainerFocused,
]}>
<Image
style={{marginStart: ResponsivePixels.size12}}
source={flagIcon}
/>
<Text
style={{
marginLeft: ResponsivePixels.size12,
color: colors.onTextMedium,
}}>
+ 91
</Text>
<TextInput
placeholder='00000 00000'
placeholderTextColor={colors.onTextLow}
value={mobileNumber}
onChangeText={handleInputChange}
style={styles.loginInput}
keyboardType='phone-pad'
onFocus={handleFocus}
onBlur={handleBlur}
/>
{console.log('mobileNumber:::', mobileNumber)}
</View>
{isLoading && (
<View style={styles.loaderContainer}>
<CommonLoader />
</View>
)}
<View style={styles.buttonContainer}>
<CustomButton
title='Continue '
primary
disabled={!isValueValid}
onPress={handleContinue}
/>
<Text style={styles.welcomeText}>
By Clicking to continue, you accept our{' '}
<Text style={{color: colors.primary}}>terms</Text> and{' '}
<Text style={{color: colors.primary}}>condition</Text>
</Text>
</View>
</View>
)
}
export default Login
const OtpScreen = () => {
const route = useRoute()
const fromBasketScreen = route.params?.fromBasketScreen || false
const navigation = useNavigation()
const dispatch = useDispatch()
const [phone, setPhone] = useState({})
const [remainingTime, setRemainingTime] = useState(10)
const [showButton, setShowButton] = useState(false)
const minutes = Math.floor(remainingTime / 60)
const seconds = remainingTime % 60
const [otpCode, setOtpCode] = useState('')
useEffect(() => {
dispatch(getMobileNumber())
.then(data => {
setPhone(data)
})
.catch(error => {
console.log(error)
})
}, [dispatch])
useEffect(() => {
if (remainingTime > 0) {
const timer = setTimeout(() => {
setRemainingTime(prevRemainingTime => prevRemainingTime - 1)
}, 1000)
return () => clearTimeout(timer)
} else {
setShowButton(true)
}
}, [remainingTime])
const handleOtpCodeChange = code => {
console.log('OTP code entered:', code);
if (code.length === 4 && code === '1234') {
console.log('fromBasketScreen', fromBasketScreen)
if (fromBasketScreen) {
navigation.navigate('Basket', {
screen: BASKET,
params: {fromBasketScreen: true},
})
console.log('fromBasketScreen', fromBasketScreen)
} else {
navigation.navigate('Account', {
screen: ACCOUNT,
params: {fromBasketScreen: false},
})
}
}
}
return (
<View style={styles.otpContainer}>
<View style={styles.otpContentContainer}>
<Header leftIcon='back' />
<Text style={styles.otpTextHeader}>
Enter OTP{'\n'}sent to your number
</Text>
<Text style={styles.otpText}>
We sent it to the number +91 {phone.mobileNumber}
</Text>
<View
style={{
marginTop: ResponsivePixels.size16,
marginHorizontal: ResponsivePixels.size10,
width: '96%',
height: '2%',
}}>
<OTPInputView
pinCount={4}
autoFocusOnLoad
codeInputFieldStyle={styles.underlineStyleHighLighted}
onCodeChanged={handleOtpCodeChange}
placeholderCharacter='•'
placeholderTextColor={colors.onTextLow}
/>
</View>
<View style={styles.resendText}>
{showButton ? (
<CustomButton
title='Resend'
primary
onPress={() => setRemainingTime(10)}
/>
) : (
<Text
style={{
color: colors.onTextLow,
fontFamily: 'Sarabun-Medium',
fontSize: ResponsivePixels.size16,
}}>
Resend code in{' '}
<Text style={{color: colors.darkBlue}}>
{String(minutes).padStart(2, '0')}:
{String(seconds).padStart(2, '0')}
</Text>
</Text>
)}
</View>
</View>
</View>
)
}
export default OtpScreen