diff --git a/apk/app/(auth)/_layout.tsx b/apk/app/(auth)/_layout.tsx
index 73c2754..5b9eb40 100644
--- a/apk/app/(auth)/_layout.tsx
+++ b/apk/app/(auth)/_layout.tsx
@@ -1,18 +1,5 @@
-import { Stack, useRouter } from "expo-router";
-import { useAuth } from "@/context/auth-context";
-import { useEffect } from "react";
+import { Stack } from "expo-router";
export default function AuthLayout() {
- const { user } = useAuth();
- const router = useRouter();
-
- useEffect(() => {
- if (user) {
- router.replace("/(tabs)");
- } else {
- router.replace("/(auth)/login");
- }
- }, [user]);
-
- return ;
-}
\ No newline at end of file
+ return ;
+}
diff --git a/apk/app/(auth)/login.tsx b/apk/app/(auth)/login.tsx
index 078099c..2b44310 100644
--- a/apk/app/(auth)/login.tsx
+++ b/apk/app/(auth)/login.tsx
@@ -48,7 +48,7 @@ function LoginScreen({ onSwitch }) {
- Don't have an account? Register
+ Don't have an account? Register
);
@@ -142,4 +142,4 @@ const styles = StyleSheet.create({
textAlign: "center",
color: "#007BFF",
},
-});
\ No newline at end of file
+});
diff --git a/apk/app/(tabs)/_layout.tsx b/apk/app/(tabs)/_layout.tsx
index 5573dcd..3d54133 100644
--- a/apk/app/(tabs)/_layout.tsx
+++ b/apk/app/(tabs)/_layout.tsx
@@ -1,13 +1,5 @@
-// app/(tabs)/_layout.tsx
-import { Redirect, Tabs } from "expo-router";
-import { useAuth } from "@/context/auth-context";
+import { Tabs } from "expo-router";
export default function TabsLayout() {
- const { user } = useAuth();
-
- if (!user) {
- return ;
- }
-
return ;
-}
\ No newline at end of file
+}
diff --git a/apk/components/scroll-view.tsx b/apk/components/scroll-view.tsx
index e7ec710..0535e3b 100644
--- a/apk/components/scroll-view.tsx
+++ b/apk/components/scroll-view.tsx
@@ -1,10 +1,8 @@
-import { StyleSheet } from "react-native";
+import { StyleSheet, View } from "react-native";
import Animated, { useAnimatedRef } from "react-native-reanimated";
-import { useColorScheme } from "@/hooks/use-color-scheme";
import { useThemeColor } from "@/hooks/use-theme-color";
import { PropsWithChildren } from "react";
-import { View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
type Props = PropsWithChildren<{
@@ -14,7 +12,6 @@ type Props = PropsWithChildren<{
export default function ScrollView({ children, headerBackgroundColor }: Props) {
const scrollRef = useAnimatedRef();
const insets = useSafeAreaInsets();
- const colorScheme = useColorScheme() ?? "light";
const backgroundColor = useThemeColor({}, "background");
return (
diff --git a/apk/components/views/root-navigation.tsx b/apk/components/views/root-navigation.tsx
index 89ae1b4..3ccd1a1 100644
--- a/apk/components/views/root-navigation.tsx
+++ b/apk/components/views/root-navigation.tsx
@@ -1,9 +1,33 @@
-import { useEffect } from "react";
-import { Stack, useRouter, useSegments } from "expo-router";
+import { BirthdaysProvider } from "@/context/birthdays-context";
import { useAuth } from "@/context/auth-context";
+import { Stack, router, useRootNavigationState, useSegments } from "expo-router";
+import { useEffect } from "react";
export default function RootLayout() {
+ const { user, isHydrated } = useAuth();
+ const navigationState = useRootNavigationState();
+ const segments = useSegments();
+
+ useEffect(() => {
+ if (!isHydrated || !navigationState?.key) {
+ return;
+ }
+
+ const inAuthGroup = segments[0] === "(auth)";
+
+ if (!user && !inAuthGroup) {
+ router.replace("/(auth)/login");
+ return;
+ }
+
+ if (user && inAuthGroup) {
+ router.replace("/(tabs)");
+ }
+ }, [isHydrated, navigationState?.key, segments, user]);
+
return (
-
+
+
+
);
-}
\ No newline at end of file
+}
diff --git a/apk/context/auth-context.tsx b/apk/context/auth-context.tsx
index 66b0900..565ed0c 100644
--- a/apk/context/auth-context.tsx
+++ b/apk/context/auth-context.tsx
@@ -7,29 +7,49 @@ interface User {
interface AuthContextValue {
user: User | null;
+ isHydrated: boolean;
login: (email: string, password: string) => Promise;
- logout: () => void;
+ logout: () => Promise;
}
const authContext = React.createContext(undefined);
+const STORAGE_KEY = "user";
export function AuthProvider({ children }: { children: React.ReactNode }) {
const [user, setUser] = React.useState(null);
+ const [isHydrated, setIsHydrated] = React.useState(false);
+
+ React.useEffect(() => {
+ const restoreUser = async () => {
+ try {
+ const storedUser = await AsyncStorage.getItem(STORAGE_KEY);
+ if (storedUser) {
+ setUser(JSON.parse(storedUser) as User);
+ }
+ } catch (error) {
+ console.log("Error restoring user", error);
+ } finally {
+ setIsHydrated(true);
+ }
+ };
+
+ restoreUser();
+ }, []);
const login = async (email: string, password: string) => {
const fakeUser = { email };
- await AsyncStorage.setItem("user", JSON.stringify(fakeUser));
+ await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(fakeUser));
setUser(fakeUser);
}
const logout = async () => {
- await AsyncStorage.removeItem("user");
+ await AsyncStorage.removeItem(STORAGE_KEY);
setUser(null);
}
return (
-
+
{children}
);
@@ -44,4 +64,3 @@ export function useAuth() {
}
-