use expo router instead of navigation

This commit is contained in:
StarAppeal
2024-12-05 21:12:40 +01:00
parent 47e493d9bd
commit 8b604d1032
13 changed files with 126 additions and 213 deletions
+3 -13
View File
@@ -1,18 +1,8 @@
import React from "react";
import {NavigationContainer} from "@react-navigation/native";
import {AuthProvider} from "@/src/context/AuthProvider";
import {ThemeProvider} from "@/src/context/ThemeProvider";
import AppNavigator from "@/src/core/AppNavigator";
import { Slot } from "expo-router";
export default function App() {
return (
<ThemeProvider>
<AuthProvider>
<NavigationContainer>
<AppNavigator />
</NavigationContainer>
</AuthProvider>
</ThemeProvider>
);
return <Slot />;
}
+21
View File
@@ -0,0 +1,21 @@
import React from "react";
import {AuthProvider} from "@/src/context/AuthProvider";
import {ThemeProvider} from "@/src/context/ThemeProvider";
import {Stack} from "expo-router";
export default function Layout() {
return (
<ThemeProvider>
<AuthProvider>
<Stack
screenOptions={{
headerShown: false
}}
/>
</AuthProvider>
</ThemeProvider>
);
}
+44
View File
@@ -0,0 +1,44 @@
import React from "react";
import {useRouter} from "expo-router";
import ThemedBackground from "../src/components/themed/ThemedBackground";
import Logo from "../src/components/Logo";
import ThemedHeader from "../src/components/themed/ThemedHeader";
import ThemedParagraph from "../src/components/themed/ThemedParagraph";
import ThemedButton from "../src/components/themed/ThemedButton";
import {useAuth} from "@/src/context/AuthProvider";
import AuthenticatedWrapper from "@/src/components/AuthenticatedWrapper";
export default function HomeScreen() {
const router = useRouter();
const {token, logout} = useAuth();
return (
<AuthenticatedWrapper>
<ThemedBackground>
<Logo/>
<ThemedHeader>Welcome 💫</ThemedHeader>
<ThemedParagraph>Congratulations you are logged in.</ThemedParagraph>
<ThemedParagraph>{token}</ThemedParagraph>
<ThemedButton
mode="outlined"
onPress={() => router.push("/protected")}>
OwO what's this?
</ThemedButton>
<ThemedButton
mode="outlined"
onPress={async () => {
await logout();
router.replace("/login");
}
}
>
Sign out
</ThemedButton>
</ThemedBackground>
</AuthenticatedWrapper>
);
}
+12 -14
View File
@@ -1,20 +1,21 @@
import React, {useEffect, useState} from "react";
import ThemedBackground from "../../src/components/themed/ThemedBackground";
import Logo from "../../src/components/Logo";
import ThemedHeader from "../../src/components/themed/ThemedHeader";
import ThemedButton from "../../src/components/themed/ThemedButton";
import ThemedTextInput from "../../src/components/themed/ThemedTextInput";
import BackButton from "../../src/components/BackButton";
import {useNavigation} from "@react-navigation/core";
import ThemedBackground from "../src/components/themed/ThemedBackground";
import Logo from "../src/components/Logo";
import ThemedHeader from "../src/components/themed/ThemedHeader";
import ThemedButton from "../src/components/themed/ThemedButton";
import ThemedTextInput from "../src/components/themed/ThemedTextInput";
import BackButton from "../src/components/BackButton";
import {useAuth} from "@/src/context/AuthProvider";
import {useTheme} from "@/src/context/ThemeProvider";
import {useRouter} from "expo-router";
export default function LoginScreen() {
const {isAuthenticated, login, logout, error} = useAuth();
const navigation = useNavigation<any>();
const router = useRouter();
const [username, setUsername] = useState({value: ""});
const [password, setPassword] = useState({value: ""});
const {toggleTheme} = useTheme();
@@ -25,10 +26,7 @@ export default function LoginScreen() {
if (isAuthenticated) {
console.log("User ist eingeloggt, weiterleiten...");
navigation.reset({
index: 0,
routes: [{name: "HomeScreen"}],
});
router.replace("/");
}
}, [isAuthenticated]);
@@ -45,7 +43,7 @@ export default function LoginScreen() {
<ThemedButton mode="contained" onPress={logout}>
Logout
</ThemedButton>
<ThemedButton mode="outlined" onPress={() => navigation.navigate("HomeScreen")}>
<ThemedButton mode="outlined" onPress={() => router.push("/")}>
Zurück
</ThemedButton>
</ThemedBackground>
@@ -54,7 +52,7 @@ export default function LoginScreen() {
return (
<ThemedBackground>
<BackButton goBack={navigation.goBack}/>
<BackButton goBack={router.back}/>
<Logo/>
<ThemedHeader>Hello.</ThemedHeader>
<ThemedTextInput
+35
View File
@@ -0,0 +1,35 @@
import React from "react";
import {useAuth} from "@/src/context/AuthProvider";
import Logo from "@/src/components/Logo";
import ThemedHeader from "@/src/components/themed/ThemedHeader";
import ThemedParagraph from "@/src/components/themed/ThemedParagraph";
import ThemedButton from "../../src/components/themed/ThemedButton";
import ThemedBackground from "@/src/components/themed/ThemedBackground";
import {useRouter} from "expo-router";
import AuthenticatedWrapper from "@/src/components/AuthenticatedWrapper";
export default function ProtectedScreen(): JSX.Element {
const router = useRouter();
const {token, logout} = useAuth();
return (
<AuthenticatedWrapper>
<ThemedBackground>
<Logo/>
<ThemedHeader>Welcome 💫</ThemedHeader>
<ThemedParagraph>Dies ist geheim. PSST !</ThemedParagraph>
<ThemedParagraph>{token}</ThemedParagraph>
<ThemedButton
mode="outlined"
onPress={async () => {
await logout();
router.replace("/login");
}
}
>
Sign out
</ThemedButton>
</ThemedBackground>
</AuthenticatedWrapper>
);
}
-44
View File
@@ -1,44 +0,0 @@
import React from "react";
import ThemedBackground from "../../src/components/themed/ThemedBackground";
import Logo from "../../src/components/Logo";
import ThemedHeader from "../../src/components/themed/ThemedHeader";
import ThemedParagraph from "../../src/components/themed/ThemedParagraph";
import ThemedButton from "../../src/components/themed/ThemedButton";
import {useNavigation} from "@react-navigation/core";
import {useAuth} from "@/src/context/AuthProvider";
export default function HomeScreen() {
console.log("HALLO LEUTE");
const navigation = useNavigation<any>();
const {token, logout} = useAuth();
return (
<ThemedBackground>
<Logo/>
<ThemedHeader>Welcome 💫</ThemedHeader>
<ThemedParagraph>Congratulations you are logged in.</ThemedParagraph>
<ThemedParagraph>{token}</ThemedParagraph>
<ThemedButton
mode="outlined"
onPress={() => navigation.navigate("ProtectedScreen")}>
OwO what's this?
</ThemedButton>
<ThemedButton
mode="outlined"
onPress={async () => {
await logout();
navigation.reset({
index: 0,
routes: [{name: "LoginScreen"}],
})
}
}
>
Sign out
</ThemedButton>
</ThemedBackground>
);
}
-35
View File
@@ -1,35 +0,0 @@
import React from "react";
import {useAuth} from "@/src/context/AuthProvider";
import Logo from "@/src/components/Logo";
import ThemedHeader from "@/src/components/themed/ThemedHeader";
import ThemedParagraph from "@/src/components/themed/ThemedParagraph";
import ThemedButton from "../../src/components/themed/ThemedButton";
import {useNavigation} from "@react-navigation/core";
import ThemedBackground from "@/src/components/themed/ThemedBackground";
export default function ProtectedScreen(): JSX.Element {
const navigation = useNavigation<any>();
const {token, logout} = useAuth();
return (
<ThemedBackground>
<Logo/>
<ThemedHeader>Welcome 💫</ThemedHeader>
<ThemedParagraph>Dies ist geheim. PSST !</ThemedParagraph>
<ThemedParagraph>{token}</ThemedParagraph>
<ThemedButton
mode="outlined"
onPress={async () => {
await logout();
navigation.reset({
index: 0,
routes: [{name: "LoginScreen"}],
})
}
}
>
Sign out
</ThemedButton>
</ThemedBackground>
);
}
+3 -23
View File
@@ -10,9 +10,6 @@
"dependencies": {
"@expo/ngrok": "^4.1.3",
"@expo/vector-icons": "^14.0.4",
"@react-navigation/bottom-tabs": "^7.1.3",
"@react-navigation/native": "^7.0.13",
"@react-navigation/stack": "^7.0.18",
"axios": "^1.7.8",
"expo": "^52.0.14",
"expo-auth-session": "^6.0.1",
@@ -36,8 +33,6 @@
"react-native-gesture-handler": "~2.21.2",
"react-native-paper": "^5.12.5",
"react-native-reanimated": "~3.16.3",
"react-native-safe-area-context": "4.14.0",
"react-native-screens": "^4.3.0",
"react-native-status-bar-height": "^2.6.0",
"react-native-web": "~0.19.13",
"react-native-webview": "13.12.4"
@@ -4623,24 +4618,6 @@
"nanoid": "3.3.7"
}
},
"node_modules/@react-navigation/stack": {
"version": "7.0.18",
"resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-7.0.18.tgz",
"integrity": "sha512-Y2Q/tgYaZIZE15ejoOFJ9vZLw8fV1x/huIP2L9qARRn427l+QACIU4TYGTBOK6PafqOlFdDmfLkDvdgjD/qwxQ==",
"license": "MIT",
"dependencies": {
"@react-navigation/elements": "^2.2.4",
"color": "^4.2.3"
},
"peerDependencies": {
"@react-navigation/native": "^7.0.13",
"react": ">= 18.2.0",
"react-native": "*",
"react-native-gesture-handler": ">= 2.0.0",
"react-native-safe-area-context": ">= 4.0.0",
"react-native-screens": ">= 4.0.0"
}
},
"node_modules/@remix-run/node": {
"version": "2.15.0",
"resolved": "https://registry.npmjs.org/@remix-run/node/-/node-2.15.0.tgz",
@@ -15251,6 +15228,7 @@
"resolved": "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.4.tgz",
"integrity": "sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=10"
},
@@ -15462,6 +15440,7 @@
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.14.0.tgz",
"integrity": "sha512-/SyYpCulWQOnnXhRq6wepkhoyQMowHm1ptDyRz20s+YS/R9mbd+mK+jFyFCyXFJn8jp7vFl43VUCgspuOiEbwA==",
"license": "MIT",
"peer": true,
"peerDependencies": {
"react": "*",
"react-native": "*"
@@ -15472,6 +15451,7 @@
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.3.0.tgz",
"integrity": "sha512-G0u8BPgu2vcRZoQTlRpBXKa0ElQSDvDBlRe6ncWwCeBmd5Uqa2I3tQ6Vn6trIE6+yneW/nD4p5wihEHlAWZPEw==",
"license": "MIT",
"peer": true,
"dependencies": {
"react-freeze": "^1.0.0",
"warn-once": "^0.1.0"
+1 -6
View File
@@ -3,7 +3,7 @@
"version": "1.0.0",
"private": true,
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
"main": "node_modules/expo/AppEntry.js",
"main": "./node_modules/expo-router/entry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
@@ -19,9 +19,6 @@
"dependencies": {
"@expo/ngrok": "^4.1.3",
"@expo/vector-icons": "^14.0.4",
"@react-navigation/bottom-tabs": "^7.1.3",
"@react-navigation/native": "^7.0.13",
"@react-navigation/stack": "^7.0.18",
"axios": "^1.7.8",
"expo": "^52.0.14",
"expo-auth-session": "^6.0.1",
@@ -45,8 +42,6 @@
"react-native-gesture-handler": "~2.21.2",
"react-native-paper": "^5.12.5",
"react-native-reanimated": "~3.16.3",
"react-native-safe-area-context": "4.14.0",
"react-native-screens": "^4.3.0",
"react-native-status-bar-height": "^2.6.0",
"react-native-web": "~0.19.13",
"react-native-webview": "13.12.4"
+2 -2
View File
@@ -1,12 +1,12 @@
import React from "react";
import {useAuth} from "@/src/context/AuthProvider";
import NotAuthenticated from "@/src/components/NotAuthenticated";
import {Redirect} from "expo-router";
const AuthenticatedWrapper: React.FC<{ children: React.ReactNode }> = ({children}) => {
const {isAuthenticated} = useAuth();
if (!isAuthenticated) {
return <NotAuthenticated />;
return <Redirect href={"/login"}/>;
}
return <>{children}</>;
+3 -3
View File
@@ -2,11 +2,11 @@ import {Image} from "react-native";
import React from "react";
import ThemedBackground from "@/src/components/themed/ThemedBackground";
import ThemedParagraph from "@/src/components/themed/ThemedParagraph";
import {useNavigation} from "@react-navigation/core";
import ThemedButton from "@/src/components/themed/ThemedButton";
import {useRouter} from "expo-router";
export default function NotAuthenticated() {
const navigation = useNavigation<any>();
const router = useRouter();
return (
<ThemedBackground>
<Image
@@ -20,7 +20,7 @@ export default function NotAuthenticated() {
<ThemedParagraph>
You are not authenticated. Please log in to view this content.
</ThemedParagraph>
<ThemedButton mode="outlined" onPress={() => navigation.navigate("LoginScreen")}>
<ThemedButton mode="outlined" onPress={() => router.push("/login")}>
Login
</ThemedButton>
</ThemedBackground>
+2
View File
@@ -49,6 +49,8 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({children}
await saveInStorage(JWT_TOKEN_KEY, response.token);
setToken(response.token);
setIsAuthenticated(true);
// correctly logged in, reset error
setError(null);
};
const logout = async () => {
-73
View File
@@ -1,73 +0,0 @@
import {useAuth} from "@/src/context/AuthProvider";
import React, {useEffect, useState} from "react";
import {StyleSheet, Text, View} from "react-native";
import {createStackNavigator} from "@react-navigation/stack";
import LoginScreen from "@/app/screens/LoginScreen";
import AuthenticatedWrapper from "@/src/components/AuthenticatedWrapper";
import HomeScreen from "@/app/screens/HomeScreen";
import ProtectedScreen from "@/app/screens/ProtectedScreen";
const Stack = createStackNavigator();
const AppNavigator = () => {
const {isAuthenticated} = useAuth(); // Auth-Status prüfen
const [initialRoute, setInitialRoute] = useState<null | string>(null);
useEffect(() => {
if (isAuthenticated === null) return;
setInitialRoute(isAuthenticated ? "HomeScreen" : "LoginScreen");
}, [isAuthenticated]);
if (initialRoute === null) {
// Ladebildschirm während der Berechnung
return (
<View style={styles.loadingContainer}>
<Text style={styles.loadingText}>Checking authentication...</Text>
</View>
);
}
console.log("Initial route:", initialRoute)
console.log("isAuthenticated:", isAuthenticated)
return (
<Stack.Navigator
initialRouteName={initialRoute}
screenOptions={{
headerShown: false,
}}
>
<Stack.Screen name="LoginScreen" component={LoginScreen}/>
<Stack.Screen name="HomeScreen">
{() => (
<AuthenticatedWrapper>
<HomeScreen/>
</AuthenticatedWrapper>
)}
</Stack.Screen>
<Stack.Screen name="ProtectedScreen">
{() => (
<AuthenticatedWrapper>
<ProtectedScreen/>
</AuthenticatedWrapper>
)}
</Stack.Screen>
</Stack.Navigator>
);
};
export default AppNavigator;
const styles = StyleSheet.create({
loadingContainer: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#f2f2f2", // Optional: Anpassen an dein Theme
},
loadingText: {
fontSize: 18,
color: "#333",
},
});