80 lines
2.3 KiB
TypeScript
80 lines
2.3 KiB
TypeScript
// app/_layout.tsx
|
|
import { Stack } from "expo-router";
|
|
import { useEffect, useState } from "react";
|
|
import { Provider, useDispatch, useSelector } from "react-redux";
|
|
import { store, AppDispatch, RootState } from "@/store";
|
|
import { PaperProvider } from "react-native-paper";
|
|
import { I18nextProvider } from "react-i18next";
|
|
import i18next from "@/services/i18n";
|
|
import SnackbarProvider from "@/contexts/Snackbar";
|
|
import * as SplashScreen from "expo-splash-screen";
|
|
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
import { STORAGE_KEYS } from "@/constants/config";
|
|
import { setIsLoggedIn } from "@/store/authSlice";
|
|
|
|
SplashScreen.preventAutoHideAsync();
|
|
|
|
export default function RootLayout() {
|
|
return (
|
|
<PaperProvider>
|
|
<SnackbarProvider>
|
|
<Provider store={store}>
|
|
<I18nextProvider i18n={i18next}>
|
|
<SplashAndAuthRouter />
|
|
</I18nextProvider>
|
|
</Provider>
|
|
</SnackbarProvider>
|
|
</PaperProvider>
|
|
);
|
|
}
|
|
|
|
function SplashAndAuthRouter() {
|
|
const dispatch = useDispatch<AppDispatch>();
|
|
const isLoggedIn = useSelector((state: RootState) => state.auth.isLoggedIn);
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
useEffect(() => {
|
|
const loadAuth = async () => {
|
|
try {
|
|
const token = await AsyncStorage.getItem(STORAGE_KEYS.AUTH_TOKEN);
|
|
|
|
if (!token) {
|
|
dispatch(setIsLoggedIn(false));
|
|
return;
|
|
}
|
|
|
|
// Token exists, now verify it by calling getUserDetails
|
|
// await dispatch(getUserDetails()).unwrap();
|
|
|
|
// If it reaches here, the token is valid
|
|
dispatch(setIsLoggedIn(true));
|
|
} catch (error) {
|
|
// getUserDetails failed => token is invalid
|
|
dispatch(setIsLoggedIn(false));
|
|
await AsyncStorage.removeItem(STORAGE_KEYS.AUTH_TOKEN); // optionally clean up
|
|
} finally {
|
|
setLoading(false);
|
|
SplashScreen.hideAsync();
|
|
}
|
|
};
|
|
|
|
loadAuth();
|
|
}, []);
|
|
|
|
if (loading) return null;
|
|
|
|
return (
|
|
<Stack screenOptions={{ headerShown: false }}>
|
|
<Stack.Protected guard={isLoggedIn}>
|
|
<Stack.Screen name="(tabs)" />
|
|
<Stack.Screen name="user" />
|
|
</Stack.Protected>
|
|
|
|
<Stack.Protected guard={!isLoggedIn}>
|
|
<Stack.Screen name="init/language" />
|
|
<Stack.Screen name="auth" />
|
|
</Stack.Protected>
|
|
</Stack>
|
|
);
|
|
}
|