feat: introduced Authentification Context
This commit is contained in:
parent
7c9fdad01f
commit
6592864bc4
9 changed files with 215 additions and 16 deletions
|
|
@ -1,15 +1,22 @@
|
|||
import { Tabs } from "expo-router/tabs";
|
||||
import {StyleSheet, View} from "react-native"
|
||||
import {StyleSheet, View, Text} from "react-native"
|
||||
|
||||
import { FontAwesome } from "@expo/vector-icons";
|
||||
import {useThemeColor} from "../../hooks/hooks";
|
||||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import { Redirect } from "expo-router";
|
||||
import { useAuth } from "../contexts/AuthContext";
|
||||
|
||||
export default function Layout() {
|
||||
// const selectedColor: string = useThemeColor( "tabIconSelected");
|
||||
// const defaultColor: string = useThemeColor("tabIconDefault");
|
||||
// const backgroundColor: string = useThemeColor("backgroundColor");
|
||||
// const tabBarColor: string = useThemeColor("tabBarColor");
|
||||
const {authState} = useAuth()
|
||||
useEffect(()=>{
|
||||
console.log(authState, "in root Layout")
|
||||
},[authState])
|
||||
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
sceneContainer: {
|
||||
|
|
@ -27,6 +34,11 @@ export default function Layout() {
|
|||
tabBarStyle: styles.tabBar,
|
||||
}
|
||||
|
||||
if(!authState?.authenticated){
|
||||
return (
|
||||
<Redirect href={"/"} />)
|
||||
}
|
||||
|
||||
return (
|
||||
<Tabs sceneContainerStyle={styles.sceneContainer} screenOptions={screenOptions}>
|
||||
<Tabs.Screen name="budget/index" options={
|
||||
|
|
|
|||
|
|
@ -6,10 +6,11 @@ import { FlatList, TextInput} from 'react-native-gesture-handler';
|
|||
import { useRef, useState, useEffect } from 'react';
|
||||
import React from 'react';
|
||||
import { useRouter } from "expo-router"
|
||||
import { useAuth } from '../../contexts/AuthContext';
|
||||
|
||||
export default function Page() {
|
||||
const router = useRouter()
|
||||
|
||||
const {onLogout} = useAuth();
|
||||
const [plusShow, setPlusShow] = useState(true);
|
||||
const prevOffset = useRef(0);
|
||||
const styles = StyleSheet.create({
|
||||
|
|
@ -52,7 +53,7 @@ export default function Page() {
|
|||
|
||||
|
||||
return (
|
||||
<View style={{flex: 1}}>
|
||||
<SafeAreaView style={{flex: 1}}>
|
||||
{plusShow && <Plus onPress={()=>{
|
||||
router.push("/(tabs)/home/addItem")
|
||||
}}/>}
|
||||
|
|
@ -61,7 +62,7 @@ export default function Page() {
|
|||
data={data}
|
||||
ListHeaderComponent={
|
||||
<>
|
||||
<Welcome name="My Dude" image={profile} onPress={()=>console.log("hello")}></Welcome>
|
||||
<Welcome name="My Dude" image={profile} onPress={onLogout!}></Welcome>
|
||||
<SearchBar placeholder='Type to Search...'></SearchBar>
|
||||
</>
|
||||
}
|
||||
|
|
@ -72,7 +73,7 @@ export default function Page() {
|
|||
scrollEventThrottle={20}
|
||||
>
|
||||
</FlatList>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
|
||||
);
|
||||
}
|
||||
12
app/_layout.tsx
Normal file
12
app/_layout.tsx
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import { Slot } from 'expo-router'
|
||||
import React from 'react'
|
||||
import { AuthProvider } from './contexts/AuthContext'
|
||||
|
||||
export default function _layout() {
|
||||
console.log("layout called")
|
||||
return (
|
||||
<AuthProvider>
|
||||
<Slot />
|
||||
</AuthProvider>
|
||||
)
|
||||
}
|
||||
137
app/contexts/AuthContext.tsx
Normal file
137
app/contexts/AuthContext.tsx
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
import { createContext, useContext, useEffect, useState } from "react";
|
||||
import { Platform } from "react-native";
|
||||
import * as SecureStore from 'expo-secure-store'
|
||||
|
||||
interface AuthProps {
|
||||
authState?: {email: string | null; authenticated: boolean | null; session: string | null};
|
||||
onRegister?: (email: string, password: string) => Promise<any>;
|
||||
onLogin?: (email: string, password: string) => Promise<any>
|
||||
onLogout?: () => void
|
||||
}
|
||||
|
||||
const SESSION_KEY = 'my_session'
|
||||
const USER_KEY = "email"
|
||||
const AuthContext = createContext<AuthProps>({})
|
||||
|
||||
export const useAuth = ()=>{
|
||||
return useContext(AuthContext)
|
||||
}
|
||||
|
||||
async function setStorageItemAsync(key: string, value: string | null){
|
||||
if (Platform.OS === 'web') {
|
||||
try {
|
||||
if (value === null) {
|
||||
localStorage.removeItem(key);
|
||||
} else {
|
||||
localStorage.setItem(key, value);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Local storage is unavailable:', e);
|
||||
}
|
||||
} else {
|
||||
if (value == null) {
|
||||
await SecureStore.deleteItemAsync(key);
|
||||
} else {
|
||||
await SecureStore.setItemAsync(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function getStorageItemAsync(key: string) : Promise<string|null> {
|
||||
if(Platform.OS === 'web'){
|
||||
return localStorage.getItem(key)
|
||||
}else{
|
||||
return SecureStore.getItemAsync(key)
|
||||
}
|
||||
}
|
||||
|
||||
export const AuthProvider = ({children}: any) => {
|
||||
const [authState, setAuthState] = useState<{
|
||||
email: string | null;
|
||||
authenticated: boolean | null;
|
||||
session : string | null;
|
||||
isLoading: boolean;
|
||||
}>({
|
||||
email: null, authenticated: null, session: null, isLoading: false
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const loadSession = async () => {
|
||||
setAuthState((prev) => {
|
||||
return {
|
||||
...prev,
|
||||
isLoading: true
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const session = await getStorageItemAsync(SESSION_KEY)
|
||||
const email = await getStorageItemAsync(USER_KEY)
|
||||
|
||||
if(session && email){
|
||||
setAuthState({
|
||||
email: email,
|
||||
authenticated: true,
|
||||
session: session,
|
||||
isLoading: false
|
||||
})
|
||||
}
|
||||
setAuthState((prev) => {
|
||||
return {
|
||||
...prev,
|
||||
isLoading: false
|
||||
}
|
||||
})
|
||||
}
|
||||
loadSession()
|
||||
},[])
|
||||
|
||||
|
||||
const register = async (email: string, password: string) => {
|
||||
//registration Logic goes here
|
||||
}
|
||||
|
||||
const login = async (email: string, password: string) => {
|
||||
|
||||
//login functionality goes here
|
||||
console.log("login called")
|
||||
setAuthState((prev) => {
|
||||
return{
|
||||
...prev,
|
||||
isLoading: true
|
||||
}
|
||||
})
|
||||
|
||||
setAuthState({
|
||||
email: email,
|
||||
authenticated: true,
|
||||
session: "super duper session token das wir vlt mal brauchen",
|
||||
isLoading: false
|
||||
|
||||
})
|
||||
|
||||
await setStorageItemAsync(SESSION_KEY, "super duper session token das wir vlt mal brauchen")
|
||||
await setStorageItemAsync(USER_KEY, email)
|
||||
}
|
||||
|
||||
const logout = async () => {
|
||||
await setStorageItemAsync(SESSION_KEY, null)
|
||||
await setStorageItemAsync(USER_KEY, null)
|
||||
|
||||
setAuthState({
|
||||
email: null,
|
||||
authenticated: false,
|
||||
session: null,
|
||||
isLoading: false
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
const value = {
|
||||
onRegister: register,
|
||||
onLogin: login,
|
||||
onLogout: logout,
|
||||
authState
|
||||
}
|
||||
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
import { View, Text } from 'react-native'
|
||||
import React from 'react'
|
||||
import { Redirect } from 'expo-router'
|
||||
|
||||
export default function index() {
|
||||
return (
|
||||
<Redirect href={"(tabs)/home"}></Redirect>
|
||||
)
|
||||
}
|
||||
14
app/index.tsx
Normal file
14
app/index.tsx
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
import React, { useEffect } from 'react'
|
||||
import { Redirect } from 'expo-router'
|
||||
import { useAuth } from './contexts/AuthContext'
|
||||
|
||||
export default function index() {
|
||||
const {authState} = useAuth()
|
||||
|
||||
|
||||
return (
|
||||
<Redirect href={authState?.authenticated ? "/home/" : "/login"}></Redirect>
|
||||
|
||||
)
|
||||
}
|
||||
22
app/login.tsx
Normal file
22
app/login.tsx
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import { View, Text } from 'react-native'
|
||||
import React, { useEffect } from 'react'
|
||||
import { useAuth } from './contexts/AuthContext'
|
||||
import { Redirect } from 'expo-router';
|
||||
|
||||
export default function login() {
|
||||
const {authState, onLogin} = useAuth();
|
||||
useEffect(() => {
|
||||
login()
|
||||
}, [])
|
||||
|
||||
|
||||
const login = async() => {
|
||||
onLogin!("test", "test");
|
||||
}
|
||||
return (
|
||||
<View>
|
||||
<Text>login</Text>
|
||||
<Redirect href={"/"}></Redirect>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
Reference in a new issue