Commit a526018f by G

navigation based on the user authentication state. Handle persistant reload auth state.

parent 470db41b
...@@ -20,9 +20,9 @@ export default function App() { ...@@ -20,9 +20,9 @@ export default function App() {
<ThemeProvider theme={theme}> <ThemeProvider theme={theme}>
<ModalsManagerProvider> <ModalsManagerProvider>
<SafeAreaProvider> <SafeAreaProvider>
<NavigationContainer> <ProvideQueryClient>
<ProvideQueryClient> <UserAuthenticationContextProvider>
<UserAuthenticationContextProvider> <NavigationContainer>
{/* <View style={styles.container}> */} {/* <View style={styles.container}> */}
{/* <SafeAreaProvider> {/* <SafeAreaProvider>
<StatusBar style="auto" /> <StatusBar style="auto" />
...@@ -30,9 +30,9 @@ export default function App() { ...@@ -30,9 +30,9 @@ export default function App() {
</SafeAreaProvider> */} </SafeAreaProvider> */}
<AppMainStackNavigator /> <AppMainStackNavigator />
{/* </View> */} {/* </View> */}
</UserAuthenticationContextProvider> </NavigationContainer>
</ProvideQueryClient> </UserAuthenticationContextProvider>
</NavigationContainer> </ProvideQueryClient>
</SafeAreaProvider> </SafeAreaProvider>
</ModalsManagerProvider> </ModalsManagerProvider>
<ModalContainer /> <ModalContainer />
......
import type { ImainStackNavigator } from "@/navigations/Types";
import type { IuserInformations } from "@/utils/requests/Types"; import type { IuserInformations } from "@/utils/requests/Types";
import authenticateUser from "@/utils/requests/authenticateUser"; import authenticateUser from "@/utils/requests/authenticateUser";
import getUserInformations from "@/utils/requests/userInformations"; import getUserInformations from "@/utils/requests/userInformations";
import { LOG } from "@logger"; import { LOG } from "@logger";
import { type NavigationProp, useNavigation } from "@react-navigation/native"; import AsyncStorage from "@react-native-async-storage/async-storage";
// import { type NavigationProp, useNavigation } from "@react-navigation/native";
import { useMutation } from "@tanstack/react-query"; import { useMutation } from "@tanstack/react-query";
import type { AxiosError } from "axios"; import type { AxiosError } from "axios";
import { createContext, useCallback, useContext, useState } from "react"; import * as SplashScreen from "expo-splash-screen";
import { createContext, useCallback, useContext, useEffect, useState } from "react";
import type { IauthenticationData } from "./Types"; import type { IauthenticationData } from "./Types";
const log = LOG.extend("UserAuthenticationContext"); const log = LOG.extend("UserAuthenticationContext");
SplashScreen.preventAutoHideAsync();
export interface UserAuthenticationContextProps { export interface UserAuthenticationContextProps {
isAuthenticated: boolean; isAuthenticated: boolean;
setIsAuthenticated: React.Dispatch<React.SetStateAction<boolean>>; setIsAuthenticated: React.Dispatch<React.SetStateAction<boolean>>;
...@@ -87,7 +90,7 @@ export const UserAuthenticationContextProvider = ({ children }: { children: Reac ...@@ -87,7 +90,7 @@ export const UserAuthenticationContextProvider = ({ children }: { children: Reac
// Hoooks // Hoooks
const navigation = useNavigation<NavigationProp<ImainStackNavigator>>(); // const navigation = useNavigation<NavigationProp<ImainStackNavigator>>();
// Mutations // Mutations
...@@ -133,7 +136,10 @@ export const UserAuthenticationContextProvider = ({ children }: { children: Reac ...@@ -133,7 +136,10 @@ export const UserAuthenticationContextProvider = ({ children }: { children: Reac
onSuccess: (userInformations) => { onSuccess: (userInformations) => {
log.info("getUserInformations request was a success, navigating to homepage"); log.info("getUserInformations request was a success, navigating to homepage");
setUserInformations(userInformations); setUserInformations(userInformations);
navigation.navigate("appBottomTabsNavigator"); setIsAuthenticated(true);
storeAuthenticationData(authenticationData);
storeUserInformations(userInformations);
// navigation.navigate("appBottomTabsNavigator");
}, },
onError: (error) => { onError: (error) => {
log.error("userInformationsMutation", error); log.error("userInformationsMutation", error);
...@@ -179,11 +185,63 @@ export const UserAuthenticationContextProvider = ({ children }: { children: Reac ...@@ -179,11 +185,63 @@ export const UserAuthenticationContextProvider = ({ children }: { children: Reac
user: 0, user: 0,
}, },
}); });
navigation.reset({ // navigation.reset({
index: 0, // index: 0,
routes: [{ name: "userLoginScreen" }], // routes: [{ name: "userLoginScreen" }],
}); // });
}, [navigation]); }, []);
// Storages
const storeAuthenticationData = async (authenticationData: IauthenticationData) => {
try {
await AsyncStorage.setItem("authenticationData", JSON.stringify(authenticationData));
} catch (e) {
log.error("storeAuthenticationData |", e);
// saving error
}
};
const storeUserInformations = async (userInformations: IuserInformations) => {
try {
await AsyncStorage.setItem("userInformations", JSON.stringify(userInformations));
} catch (e) {
log.error("storeUserInformations |", e);
// saving error
}
};
const loadAuthenticationData = async () => {
log.debug("loadAuthenticationData | Loading authentication data");
const jsonRepresentation = await AsyncStorage.getItem("authenticationData");
return jsonRepresentation ? JSON.parse(jsonRepresentation) : null;
};
const loadUserInformations = async () => {
log.debug("loadUserInformations | Loading user informations");
const jsonRepresentation = await AsyncStorage.getItem("userInformations");
return jsonRepresentation ? JSON.parse(jsonRepresentation) : null;
};
// biome-ignore lint/correctness/useExhaustiveDependencies: <This should only be executed once. At startup.>
useEffect(() => {
log.debug("UserAuthenticationContext | App Startup | loading saved user data.");
(async () => {
try {
const authenticationData = await loadAuthenticationData();
const userInformations = await loadUserInformations();
if (authenticationData && userInformations) {
setAuthenticationData(authenticationData);
setUserInformations(userInformations);
setIsAuthenticated(true);
// navigation.navigate("appBottomTabsNavigator");
}
} catch (error) {
} finally {
await SplashScreen.hideAsync();
}
})();
}, []);
return ( return (
<UserAuthenticationContext.Provider <UserAuthenticationContext.Provider
......
import { useUserAuthenticationContext } from "@/contexts/UserAuthenticationContext";
import { LOG } from "@logger";
import { createNativeStackNavigator } from "@react-navigation/native-stack"; import { createNativeStackNavigator } from "@react-navigation/native-stack";
import HomeUserNotLoggedIn from "@screens/HomeUserNotLoggedIn"; import HomeUserNotLoggedIn from "@screens/HomeUserNotLoggedIn";
import PaymentResultScreen from "@screens/PaymentResultScreen"; import PaymentResultScreen from "@screens/PaymentResultScreen";
import UserLoginScreen from "@screens/UserLoginScreen"; import UserLoginScreen from "@screens/UserLoginScreen";
import WaveQrCodePaymentScreen from "@screens/WaveQrCodePaymentScreen"; import WaveQrCodePaymentScreen from "@screens/WaveQrCodePaymentScreen";
import * as SplashScreen from "expo-splash-screen";
import { AppBottomTabsNavigator } from "./AppBottomTabsNavigator"; import { AppBottomTabsNavigator } from "./AppBottomTabsNavigator";
import type { ImainStackNavigator } from "./Types"; import type { ImainStackNavigator } from "./Types";
const Stack = createNativeStackNavigator<ImainStackNavigator>(); const Stack = createNativeStackNavigator<ImainStackNavigator>();
const log = LOG.extend("AppMainStackNavigator");
SplashScreen.preventAutoHideAsync();
const AppMainStackNavigator = () => { const AppMainStackNavigator = () => {
const { isAuthenticated, isAuthenticating } = useUserAuthenticationContext();
if (isAuthenticating) {
log.info("isAuthenticating");
return null;
}
async () => {
await SplashScreen.hideAsync();
};
if (!isAuthenticating && !isAuthenticated) {
log.info("Navigating to UserLoginScreen");
return (
<Stack.Navigator
initialRouteName="homeUserNotLoggedIn"
screenOptions={{ headerShown: false }}
>
<Stack.Screen name="homeUserNotLoggedIn" component={HomeUserNotLoggedIn} />
<Stack.Screen name="userLoginScreen" component={UserLoginScreen} />
</Stack.Navigator>
);
}
log.info("Navigating to AppBottomTabsNavigator");
return ( return (
<Stack.Navigator <Stack.Navigator
initialRouteName="homeUserNotLoggedIn" initialRouteName="appBottomTabsNavigator"
screenOptions={{ headerShown: false }} screenOptions={{ headerShown: false }}
> >
<Stack.Screen name="homeUserNotLoggedIn" component={HomeUserNotLoggedIn} /> {/* <Stack.Screen name="homeUserNotLoggedIn" component={HomeUserNotLoggedIn} />
<Stack.Screen name="userLoginScreen" component={UserLoginScreen} /> <Stack.Screen name="userLoginScreen" component={UserLoginScreen} /> */}
<Stack.Screen name="appBottomTabsNavigator" component={AppBottomTabsNavigator} /> <Stack.Screen name="appBottomTabsNavigator" component={AppBottomTabsNavigator} />
<Stack.Screen name="paymentResultScreen" component={PaymentResultScreen} /> <Stack.Screen name="paymentResultScreen" component={PaymentResultScreen} />
<Stack.Screen name="waveQrCodePaymentScreen" component={WaveQrCodePaymentScreen} /> <Stack.Screen name="waveQrCodePaymentScreen" component={WaveQrCodePaymentScreen} />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment