mirror of
https://github.com/SrIzan10/featheroom.git
synced 2026-06-06 00:56:49 +00:00
chore: google auth screens
This commit is contained in:
@@ -1,28 +0,0 @@
|
||||
import { View } from 'react-native'
|
||||
import { Button, Text } from 'react-native-paper'
|
||||
|
||||
import { useAuth } from '@/lib/providers/auth'
|
||||
|
||||
function Layout() {
|
||||
const { signIn, user } = useAuth()
|
||||
|
||||
return (
|
||||
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
|
||||
<Button onPress={async () => await signIn()}>log in!</Button>
|
||||
<Text>this is {JSON.stringify(user)}.</Text>
|
||||
</View>
|
||||
/* <Stack
|
||||
screenOptions={{
|
||||
animation: 'slide_from_bottom',
|
||||
header: (props) => (
|
||||
<StackHeader navProps={props} children={undefined} />
|
||||
),
|
||||
}}
|
||||
>
|
||||
<Stack.Screen name="login" options={{ title: 'Log in' }} />
|
||||
<Stack.Screen name="signup" options={{ title: 'Sign up' }} />
|
||||
</Stack> */
|
||||
)
|
||||
}
|
||||
|
||||
export default Layout
|
||||
@@ -1,107 +1,7 @@
|
||||
import { Image } from 'expo-image'
|
||||
import { router } from 'expo-router'
|
||||
import { Formik } from 'formik'
|
||||
import React from 'react'
|
||||
import {
|
||||
Button,
|
||||
Surface,
|
||||
TextInput,
|
||||
HelperText,
|
||||
Text,
|
||||
} from 'react-native-paper'
|
||||
import * as Yup from 'yup'
|
||||
import { Text } from "react-native-paper";
|
||||
|
||||
import { styles } from '@/lib/ui'
|
||||
|
||||
const Login = () => (
|
||||
<Surface style={{ ...styles.screen, alignItems: undefined }}>
|
||||
<Image
|
||||
alt="Logo"
|
||||
source={require('@/assets/images/icon.png')}
|
||||
style={{
|
||||
height: 150,
|
||||
width: 150,
|
||||
borderRadius: 16,
|
||||
marginBottom: 32,
|
||||
marginHorizontal: 'auto',
|
||||
}}
|
||||
/>
|
||||
|
||||
<Text variant="headlineLarge" style={{ textAlign: 'center' }}>
|
||||
Welcome to ERNP
|
||||
</Text>
|
||||
<Text variant="bodyLarge" style={{ textAlign: 'center' }}>
|
||||
We're excited to have you back. Please log in to continue.
|
||||
</Text>
|
||||
|
||||
<Formik
|
||||
initialValues={{ username: '', password: '' }}
|
||||
onSubmit={(values) => console.log(values)}
|
||||
validationSchema={Yup.object().shape({
|
||||
username: Yup.string()
|
||||
.min(3, 'Too Short!')
|
||||
.max(64, 'Too Long!')
|
||||
.required('Please enter a username.'),
|
||||
password: Yup.string()
|
||||
.min(8, 'Too Short! must be at least 8 characters.')
|
||||
.max(64, 'Too Long!')
|
||||
.matches(
|
||||
/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*])/,
|
||||
'Must 1 uppercase, 1 lowercase, 1 number and 1 special case character',
|
||||
)
|
||||
.required('Please enter a password'),
|
||||
})}
|
||||
>
|
||||
{({ handleChange, handleBlur, handleSubmit, values, errors }) => (
|
||||
<>
|
||||
<Surface elevation={0}>
|
||||
<TextInput
|
||||
maxLength={64}
|
||||
mode="outlined"
|
||||
label="Username"
|
||||
value={values.username}
|
||||
error={!!errors.username}
|
||||
onBlur={handleBlur('username')}
|
||||
right={64 - values.username.length}
|
||||
placeholder="Enter your username..."
|
||||
onChangeText={handleChange('username')}
|
||||
/>
|
||||
<HelperText type="error" visible={!!errors.username}>
|
||||
{errors.username}
|
||||
</HelperText>
|
||||
</Surface>
|
||||
|
||||
<Surface elevation={0}>
|
||||
<TextInput
|
||||
maxLength={64}
|
||||
mode="outlined"
|
||||
label="Password"
|
||||
value={values.password}
|
||||
error={!!errors.password}
|
||||
onBlur={handleBlur('password')}
|
||||
right={64 - values.password.length}
|
||||
placeholder="Enter your password..."
|
||||
onChangeText={handleChange('password')}
|
||||
/>
|
||||
<HelperText type="error" visible={!!errors.password}>
|
||||
{errors.password}
|
||||
</HelperText>
|
||||
</Surface>
|
||||
|
||||
<Button mode="contained" onPress={() => handleSubmit()}>
|
||||
Login
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</Formik>
|
||||
|
||||
<Button
|
||||
mode="contained-tonal"
|
||||
onPress={() => router.push('/(auth)/signup')}
|
||||
>
|
||||
New here?
|
||||
</Button>
|
||||
</Surface>
|
||||
)
|
||||
|
||||
export default Login
|
||||
export default function Login() {
|
||||
return (
|
||||
<Text>Login please</Text>
|
||||
)
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
import { Image } from 'expo-image'
|
||||
import { router } from 'expo-router'
|
||||
import { Formik } from 'formik'
|
||||
import React from 'react'
|
||||
import { ScrollView } from 'react-native'
|
||||
import {
|
||||
Button,
|
||||
Surface,
|
||||
TextInput,
|
||||
HelperText,
|
||||
Text,
|
||||
} from 'react-native-paper'
|
||||
import * as Yup from 'yup'
|
||||
|
||||
import { styles } from '@/lib/ui'
|
||||
|
||||
const SignUp = () => (
|
||||
<ScrollView style={{ flex: 1 }}>
|
||||
<Surface style={{ ...styles.screen, alignItems: undefined }}>
|
||||
<Image
|
||||
alt="Logo"
|
||||
source={require('@/assets/images/icon.png')}
|
||||
style={{
|
||||
height: 150,
|
||||
width: 150,
|
||||
borderRadius: 16,
|
||||
marginBottom: 32,
|
||||
marginHorizontal: 'auto',
|
||||
}}
|
||||
/>
|
||||
|
||||
<Text variant="headlineLarge" style={{ textAlign: 'center' }}>
|
||||
Join ERNP Today!
|
||||
</Text>
|
||||
<Text variant="bodyLarge" style={{ textAlign: 'center' }}>
|
||||
We're thrilled to have you on board. Let's get you set up.
|
||||
</Text>
|
||||
|
||||
<Formik
|
||||
initialValues={{
|
||||
username: '',
|
||||
password: '',
|
||||
email: '',
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
}}
|
||||
onSubmit={(values) => console.log(values)}
|
||||
validationSchema={Yup.object().shape({
|
||||
username: Yup.string()
|
||||
.min(3, 'Too Short!')
|
||||
.max(64, 'Too Long!')
|
||||
.required('Please enter a username.'),
|
||||
password: Yup.string()
|
||||
.min(8, 'Too Short! must be at least 8 characters.')
|
||||
.max(64, 'Too Long!')
|
||||
.matches(
|
||||
/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*])/,
|
||||
'Must 1 uppercase, 1 lowercase, 1 number and 1 special case character',
|
||||
)
|
||||
.required('Please enter a password'),
|
||||
email: Yup.string().email().required('Please enter an email.'),
|
||||
firstName: Yup.string()
|
||||
.min(3, 'Too Short!')
|
||||
.max(64, 'Too Long!')
|
||||
.required('Please enter a first name.'),
|
||||
lastName: Yup.string()
|
||||
.min(3, 'Too Short!')
|
||||
.max(64, 'Too Long!')
|
||||
.required('Please enter a last name.'),
|
||||
})}
|
||||
>
|
||||
{({ handleChange, handleBlur, handleSubmit, values, errors }) => (
|
||||
<>
|
||||
<Surface elevation={0}>
|
||||
<TextInput
|
||||
maxLength={64}
|
||||
mode="outlined"
|
||||
label="Username"
|
||||
value={values.username}
|
||||
error={!!errors.username}
|
||||
onBlur={handleBlur('username')}
|
||||
right={64 - values.username.length}
|
||||
placeholder="Enter your username..."
|
||||
onChangeText={handleChange('username')}
|
||||
/>
|
||||
<HelperText type="error" visible={!!errors.username}>
|
||||
{errors.username}
|
||||
</HelperText>
|
||||
</Surface>
|
||||
|
||||
<Surface elevation={0}>
|
||||
<TextInput
|
||||
maxLength={64}
|
||||
mode="outlined"
|
||||
label="Password"
|
||||
value={values.password}
|
||||
error={!!errors.password}
|
||||
onBlur={handleBlur('password')}
|
||||
right={64 - values.password.length}
|
||||
placeholder="Enter your password..."
|
||||
onChangeText={handleChange('password')}
|
||||
/>
|
||||
<HelperText type="error" visible={!!errors.password}>
|
||||
{errors.password}
|
||||
</HelperText>
|
||||
</Surface>
|
||||
|
||||
<Surface elevation={0}>
|
||||
<TextInput
|
||||
maxLength={64}
|
||||
mode="outlined"
|
||||
label="Email"
|
||||
value={values.email}
|
||||
error={!!errors.email}
|
||||
onBlur={handleBlur('email')}
|
||||
right={64 - values.email.length}
|
||||
placeholder="Enter your email..."
|
||||
onChangeText={handleChange('email')}
|
||||
/>
|
||||
<HelperText type="error" visible={!!errors.email}>
|
||||
{errors.email}
|
||||
</HelperText>
|
||||
</Surface>
|
||||
|
||||
<Surface elevation={0}>
|
||||
<TextInput
|
||||
maxLength={64}
|
||||
mode="outlined"
|
||||
label="First name"
|
||||
value={values.firstName}
|
||||
error={!!errors.firstName}
|
||||
onBlur={handleBlur('firstName')}
|
||||
right={64 - values.firstName.length}
|
||||
placeholder="Enter your first name..."
|
||||
onChangeText={handleChange('firstName')}
|
||||
/>
|
||||
<HelperText type="error" visible={!!errors.firstName}>
|
||||
{errors.firstName}
|
||||
</HelperText>
|
||||
</Surface>
|
||||
|
||||
<Surface elevation={0}>
|
||||
<TextInput
|
||||
maxLength={64}
|
||||
mode="outlined"
|
||||
label="Last name"
|
||||
value={values.lastName}
|
||||
error={!!errors.lastName}
|
||||
onBlur={handleBlur('lastName')}
|
||||
right={64 - values.lastName.length}
|
||||
placeholder="Enter your first name..."
|
||||
onChangeText={handleChange('lastName')}
|
||||
/>
|
||||
<HelperText type="error" visible={!!errors.lastName}>
|
||||
{errors.lastName}
|
||||
</HelperText>
|
||||
</Surface>
|
||||
|
||||
<Button mode="contained" onPress={() => handleSubmit()}>
|
||||
Sign up
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</Formik>
|
||||
|
||||
<Button
|
||||
mode="contained-tonal"
|
||||
onPress={() => router.push('/(auth)/login')}
|
||||
>
|
||||
Already have an account?
|
||||
</Button>
|
||||
</Surface>
|
||||
</ScrollView>
|
||||
)
|
||||
|
||||
export default SignUp
|
||||
@@ -68,35 +68,6 @@ const TabLayout = () => {
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Tabs.Screen
|
||||
name="profile"
|
||||
options={{
|
||||
title: 'Profile',
|
||||
headerRight: () => (
|
||||
<>
|
||||
<Tooltip title="Search">
|
||||
<Appbar.Action
|
||||
icon="magnify"
|
||||
onPress={() => router.push('/search')}
|
||||
/>
|
||||
</Tooltip>
|
||||
<Tooltip title="Settings">
|
||||
<Appbar.Action
|
||||
icon="cog"
|
||||
onPress={() => router.push('/(tabs)/settings')}
|
||||
/>
|
||||
</Tooltip>
|
||||
</>
|
||||
),
|
||||
tabBarIcon: (props) => (
|
||||
<MaterialCommunityIcons
|
||||
{...props}
|
||||
size={24}
|
||||
name={props.focused ? 'account' : 'account-outline'}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Tabs.Screen
|
||||
name="settings"
|
||||
options={{
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
import { router } from 'expo-router'
|
||||
import React from 'react'
|
||||
import { Button, Surface } from 'react-native-paper'
|
||||
|
||||
import { ScreenInfo, styles } from '@/lib/ui'
|
||||
|
||||
const Profile = () => (
|
||||
<Surface style={styles.screen}>
|
||||
<ScreenInfo title="Profile" path="app/(tabs)/profile.tsx" />
|
||||
|
||||
<Surface
|
||||
elevation={0}
|
||||
style={{
|
||||
padding: 16,
|
||||
gap: 16,
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
}}
|
||||
>
|
||||
<Button mode="contained" onPress={() => router.push('/(auth)/login')}>
|
||||
Login
|
||||
</Button>
|
||||
|
||||
<Button mode="contained" onPress={() => router.push('/(auth)/signup')}>
|
||||
Sign Up
|
||||
</Button>
|
||||
</Surface>
|
||||
</Surface>
|
||||
)
|
||||
|
||||
export default Profile
|
||||
@@ -13,11 +13,15 @@ import {
|
||||
|
||||
import { Color, Setting } from '@/lib/types'
|
||||
import { Colors, LoadingIndicator, ScreenInfo, styles } from '@/lib/ui'
|
||||
import { reloadAppAsync } from 'expo'
|
||||
import { useAuth } from '@/lib/providers/auth'
|
||||
import { Image } from 'expo-image'
|
||||
|
||||
const Settings = () => {
|
||||
const colorScheme = useColorScheme()
|
||||
const [loading, setLoading] = React.useState<boolean>(false)
|
||||
const [message, setMessage] = React.useState({ visible: false, content: '' })
|
||||
const { user, signIn, signOut } = useAuth()
|
||||
const [settings, setSettings] = React.useState<Setting>({
|
||||
color: 'default',
|
||||
theme: 'auto',
|
||||
@@ -204,42 +208,72 @@ const Settings = () => {
|
||||
</Menu>
|
||||
)}
|
||||
/>
|
||||
<Button
|
||||
mode="contained"
|
||||
style={{ margin: 16 }}
|
||||
icon="content-save"
|
||||
onPress={() =>
|
||||
SecureStore.setItemAsync('settings', JSON.stringify(settings))
|
||||
.then(async () => {
|
||||
setMessage({
|
||||
visible: true,
|
||||
content: 'Restarting app...',
|
||||
})
|
||||
await reloadAppAsync()
|
||||
})
|
||||
.catch((res) =>
|
||||
setMessage({
|
||||
visible: true,
|
||||
content: res.message,
|
||||
}),
|
||||
)
|
||||
}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</List.Accordion>
|
||||
</List.AccordionGroup>
|
||||
</Surface>
|
||||
)}
|
||||
|
||||
<Surface elevation={0} style={styles.screen}>
|
||||
<ScreenInfo title="Settings" path="app/(tabs)/settings.tsx" />
|
||||
{/* make a surface for the authentication */}
|
||||
<Surface elevation={0}>
|
||||
<List.Accordion
|
||||
id="2"
|
||||
title="Authentication"
|
||||
left={(props) => <List.Icon {...props} icon={'account'} />}
|
||||
>
|
||||
{user ? (
|
||||
<>
|
||||
<List.Item
|
||||
title={`Hey ${user.user.givenName}!`}
|
||||
description="Click here to check more info"
|
||||
left={(props) => <List.Icon {...props} icon="fingerprint" />}
|
||||
/>
|
||||
<List.Item
|
||||
title="Sign Out"
|
||||
description="Sign out of your account"
|
||||
left={(props) => <List.Icon {...props} icon="logout" />}
|
||||
onPress={async () => {
|
||||
await signOut()
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<List.Item
|
||||
title="Login"
|
||||
description="Log in to your account"
|
||||
left={(props) => <List.Icon {...props} icon="login" />}
|
||||
onPress={async () => {
|
||||
await signIn()
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</List.Accordion>
|
||||
</Surface>
|
||||
|
||||
<Button
|
||||
mode="contained"
|
||||
style={{ margin: 16 }}
|
||||
onPress={() =>
|
||||
Platform.OS !== 'web'
|
||||
? SecureStore.setItemAsync('settings', JSON.stringify(settings))
|
||||
.then(() =>
|
||||
setMessage({
|
||||
visible: true,
|
||||
content: 'Please restart the app to apply changes.',
|
||||
}),
|
||||
)
|
||||
.catch((res) =>
|
||||
setMessage({
|
||||
visible: true,
|
||||
content: res.message,
|
||||
}),
|
||||
)
|
||||
: setMessage({
|
||||
visible: true,
|
||||
content: 'This feature is not available on the web.',
|
||||
})
|
||||
}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
|
||||
<Snackbar
|
||||
visible={message.visible}
|
||||
onDismiss={() => setMessage({ ...message, visible: false })}
|
||||
|
||||
@@ -4,15 +4,15 @@ import {
|
||||
JetBrainsMono_400Regular,
|
||||
} from '@expo-google-fonts/jetbrains-mono'
|
||||
import { NotoSans_400Regular } from '@expo-google-fonts/noto-sans'
|
||||
import { SplashScreen, Stack } from 'expo-router'
|
||||
import { Redirect, SplashScreen, Stack, useRootNavigationState, useRouter } from 'expo-router'
|
||||
import * as SecureStore from 'expo-secure-store'
|
||||
import React from 'react'
|
||||
import { Platform, useColorScheme } from 'react-native'
|
||||
import { PaperProvider } from 'react-native-paper'
|
||||
|
||||
import { AuthProvider, useAuth } from '@/lib/providers/auth'
|
||||
import { Setting } from '@/lib/types'
|
||||
import { StackHeader, Themes } from '@/lib/ui'
|
||||
import { AuthProvider } from '@/lib/providers/auth'
|
||||
|
||||
export {
|
||||
// Catch any errors thrown by the Layout component.
|
||||
@@ -34,6 +34,9 @@ const RootLayout = () => {
|
||||
...MaterialCommunityIcons.font,
|
||||
})
|
||||
|
||||
// Get authentication state
|
||||
const rootNavigationState = useRootNavigationState()
|
||||
|
||||
// Expo Router uses Error Boundaries to catch errors in the navigation tree.
|
||||
React.useEffect(() => {
|
||||
if (error) throw error
|
||||
@@ -45,7 +48,8 @@ const RootLayout = () => {
|
||||
}
|
||||
}, [loaded])
|
||||
|
||||
if (!loaded) {
|
||||
// Make sure we have the navigation state before showing content
|
||||
if (!loaded || !rootNavigationState) {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -61,32 +65,28 @@ const RootLayoutNav = () => {
|
||||
|
||||
// Load settings from the device
|
||||
React.useEffect(() => {
|
||||
if (Platform.OS !== 'web') {
|
||||
SecureStore.getItemAsync('settings').then((result) => {
|
||||
if (result === null) {
|
||||
SecureStore.setItemAsync('settings', JSON.stringify(settings)).then(
|
||||
(res) => console.log(res),
|
||||
)
|
||||
}
|
||||
SecureStore.getItemAsync('settings').then((result) => {
|
||||
if (result === null) {
|
||||
SecureStore.setItemAsync('settings', JSON.stringify(settings)).then(
|
||||
(res) => console.log(res),
|
||||
)
|
||||
}
|
||||
|
||||
setSettings(JSON.parse(result ?? JSON.stringify(settings)))
|
||||
})
|
||||
} else {
|
||||
setSettings({ ...settings, theme: colorScheme ?? 'light' })
|
||||
}
|
||||
setSettings(JSON.parse(result ?? JSON.stringify(settings)))
|
||||
})
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<PaperProvider
|
||||
theme={
|
||||
Themes[
|
||||
settings.theme === 'auto' ? (colorScheme ?? 'dark') : settings.theme
|
||||
][settings.color]
|
||||
}
|
||||
>
|
||||
<AuthProvider>
|
||||
<AuthProvider>
|
||||
<PaperProvider
|
||||
theme={
|
||||
Themes[
|
||||
settings.theme === 'auto' ? (colorScheme ?? 'dark') : settings.theme
|
||||
][settings.color]
|
||||
}
|
||||
>
|
||||
<Stack
|
||||
screenOptions={{
|
||||
animation: 'slide_from_bottom',
|
||||
@@ -95,7 +95,6 @@ const RootLayoutNav = () => {
|
||||
),
|
||||
}}
|
||||
>
|
||||
<Stack.Screen name="(auth)" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="drawer" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="search" options={{ title: 'Search' }} />
|
||||
@@ -104,8 +103,8 @@ const RootLayoutNav = () => {
|
||||
options={{ title: 'Modal', presentation: 'modal' }}
|
||||
/>
|
||||
</Stack>
|
||||
</AuthProvider>
|
||||
</PaperProvider>
|
||||
</PaperProvider>
|
||||
</AuthProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -77,29 +77,6 @@ const DrawerLayout = () => {
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Drawer.Screen
|
||||
name="profile"
|
||||
options={{
|
||||
drawerLabel: 'Profile',
|
||||
title: 'Profile',
|
||||
headerRight: () => (
|
||||
<>
|
||||
<Tooltip title="Search">
|
||||
<Appbar.Action
|
||||
icon="magnify"
|
||||
onPress={() => router.push('/search')}
|
||||
/>
|
||||
</Tooltip>
|
||||
<Tooltip title="Settings">
|
||||
<Appbar.Action
|
||||
icon="cog"
|
||||
onPress={() => router.push('/(tabs)/settings')}
|
||||
/>
|
||||
</Tooltip>
|
||||
</>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Drawer.Screen
|
||||
name="settings"
|
||||
options={{
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
import { router } from 'expo-router'
|
||||
import React from 'react'
|
||||
import { Button, Surface } from 'react-native-paper'
|
||||
|
||||
import { ScreenInfo, styles } from '@/lib/ui'
|
||||
|
||||
const Profile = () => (
|
||||
<Surface style={styles.screen}>
|
||||
<ScreenInfo title="Profile" path="app/(tabs)/profile.tsx" />
|
||||
|
||||
<Surface
|
||||
elevation={0}
|
||||
style={{
|
||||
padding: 16,
|
||||
gap: 16,
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
}}
|
||||
>
|
||||
<Button mode="contained" onPress={() => router.push('/(auth)/login')}>
|
||||
Login
|
||||
</Button>
|
||||
|
||||
<Button mode="contained" onPress={() => router.push('/(auth)/signup')}>
|
||||
Sign Up
|
||||
</Button>
|
||||
</Surface>
|
||||
</Surface>
|
||||
)
|
||||
|
||||
export default Profile
|
||||
@@ -2,7 +2,13 @@ import {
|
||||
GoogleSignin,
|
||||
type User,
|
||||
} from '@react-native-google-signin/google-signin'
|
||||
import { createContext, useContext, useEffect, useState, type ReactNode } from 'react'
|
||||
import {
|
||||
createContext,
|
||||
useContext,
|
||||
useEffect,
|
||||
useState,
|
||||
type ReactNode,
|
||||
} from 'react'
|
||||
|
||||
interface AuthProviderProps {
|
||||
children: ReactNode
|
||||
|
||||
@@ -20,12 +20,6 @@ const DrawerContent = (props: DrawerContentProps) => (
|
||||
active={props.navProps.state.index === 0}
|
||||
onPress={() => router.push('/drawer')}
|
||||
/>
|
||||
<Drawer.Item
|
||||
label="Profile"
|
||||
icon="account"
|
||||
active={props.navProps.state.index === 1}
|
||||
onPress={() => router.push('/drawer/profile')}
|
||||
/>
|
||||
<Drawer.Item
|
||||
label="Settings"
|
||||
icon="cog"
|
||||
|
||||
Reference in New Issue
Block a user