diff --git a/client/app/(tabs)/_layout.tsx b/client/app/(tabs)/_layout.tsx index 721fba7..92b529c 100644 --- a/client/app/(tabs)/_layout.tsx +++ b/client/app/(tabs)/_layout.tsx @@ -2,10 +2,18 @@ import { Tabs } from 'expo-router' import React from 'react' import { FontAwesome6, MaterialIcons } from '@expo/vector-icons' import TabBar from '@/components/ui/TabBar' +import TabsHeader from '@/components/ui/TabsHeader' export default function TabLayout() { return ( - }> + <> + } + screenOptions={{ + tabBarHideOnKeyboard: true, + header: (props) => , + }} + > + ) } diff --git a/client/app/_layout.tsx b/client/app/_layout.tsx index 3b2285b..d0c2601 100644 --- a/client/app/_layout.tsx +++ b/client/app/_layout.tsx @@ -9,6 +9,7 @@ import * as SecureStore from '@/utils/SecureStore' import { useStartGeolocationServiceEffect } from '@/utils/geolocation' import { useEffect } from 'react' import { useRouteInfo } from 'expo-router/build/hooks' +import TabsHeader from '@/components/ui/TabsHeader' export default function RootLayout() { useStartGeolocationServiceEffect() @@ -29,7 +30,7 @@ export default function RootLayout() { - + diff --git a/client/app/login.tsx b/client/app/login.tsx index 59fc8f5..8a775cd 100644 --- a/client/app/login.tsx +++ b/client/app/login.tsx @@ -2,10 +2,12 @@ import * as SecureStore from "@/utils/SecureStore" import { useRouter } from "expo-router" import { useRef, useState } from "react" import { Platform } from "react-native" -import { Button, Dialog, Portal, Surface, Text, TextInput } from "react-native-paper" +import { Appbar, Button, Dialog, Portal, Surface, Text, TextInput } from "react-native-paper" export default function Login() { const router = useRouter() + const [isLoggedIn, setIsLoggedIn] = useState(SecureStore.getItem("apiToken") !== null) + console.log(SecureStore.getItem("apiToken")) const [name, setName] = useState(SecureStore.getItem('apiName') ?? "") const [password, setPassword] = useState("") const [errorDialogVisible, setErrorDialogVisible] = useState(false) @@ -17,7 +19,7 @@ export default function Login() { const hideErrorDialog = () => setErrorDialogVisible(false) - async function onLogin() { + async function login() { const resp = await fetch("http://192.168.1.198:3000/auth/login/", { method: "POST", headers: { "Content-Type": "application/json" }, @@ -49,8 +51,20 @@ export default function Login() { router.navigate('/') } + async function logout() { + await SecureStore.deleteItemAsync("apiName") + await SecureStore.deleteItemAsync("apiPassword") + await SecureStore.deleteItemAsync("apiToken") + setIsLoggedIn(false) + } + return ( + + {isLoggedIn && router.canGoBack() ? router.back()} /> : undefined} + + {isLoggedIn ? : undefined} + setPassword(text)} - onSubmitEditing={onLogin} + onSubmitEditing={login} secureTextEntry={true} style={{ margin: 8 }} /> - diff --git a/client/components/LoginButton.tsx b/client/components/LoginButton.tsx new file mode 100644 index 0000000..e69de29 diff --git a/client/components/ui/TabsHeader.tsx b/client/components/ui/TabsHeader.tsx new file mode 100644 index 0000000..e96d2c1 --- /dev/null +++ b/client/components/ui/TabsHeader.tsx @@ -0,0 +1,66 @@ +import { BottomTabHeaderProps } from '@react-navigation/bottom-tabs' +import { getHeaderTitle } from '@react-navigation/elements' +import React from 'react' +import { + Appbar, + AppbarProps, + IconButton, + Searchbar, + SearchbarProps, + Tooltip, +} from 'react-native-paper' + +interface TabsHeaderProps extends AppbarProps { + navProps: BottomTabHeaderProps + withSearchBar?: boolean + searchBarProps?: SearchbarProps +} + +const TabsHeader = (props: TabsHeaderProps) => { + const [query, setQuery] = React.useState('') + + return props.withSearchBar ? ( + + ( + + + props.searchBarProps?.onChangeText + ? props.searchBarProps.onChangeText(query) + : undefined + } + /> + + )} + /> + + ) : ( + + {props.navProps.options.headerLeft + ? props.navProps.options.headerLeft({}) + : undefined} + + + + {props.navProps.options.headerRight + ? props.navProps.options.headerRight({ + canGoBack: props.navProps.navigation.canGoBack(), + }) + : undefined} + + ) +} + +export default TabsHeader \ No newline at end of file diff --git a/client/utils/SecureStore.ts b/client/utils/SecureStore.ts index bbb51aa..5cfb1d9 100644 --- a/client/utils/SecureStore.ts +++ b/client/utils/SecureStore.ts @@ -1,3 +1,3 @@ -import { getItem, getItemAsync, setItem, setItemAsync } from 'expo-secure-store' +import { deleteItemAsync, getItem, getItemAsync, setItem, setItemAsync } from 'expo-secure-store' -export { getItem, getItemAsync, setItem, setItemAsync } +export { deleteItemAsync, getItem, getItemAsync, setItem, setItemAsync } diff --git a/client/utils/SecureStore.web.ts b/client/utils/SecureStore.web.ts index 77adfbc..ed0822b 100644 --- a/client/utils/SecureStore.web.ts +++ b/client/utils/SecureStore.web.ts @@ -1,3 +1,7 @@ +export async function deleteItemAsync(key: string): Promise { + return localStorage.removeItem(key) +} + export function getItem(key: string): string | null { return localStorage.getItem(key) }