updating to use clerk auth with new routing to signin page by default
This commit is contained in:
12
app/(auth)/_layout.tsx
Normal file
12
app/(auth)/_layout.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import { useAuth } from '@clerk/clerk-expo'
|
||||
import { Redirect, Stack } from 'expo-router'
|
||||
|
||||
export default function AuthRoutesLayout() {
|
||||
const { isSignedIn } = useAuth()
|
||||
|
||||
if (isSignedIn) {
|
||||
return <Redirect href={'/'} />
|
||||
}
|
||||
|
||||
return <Stack screenOptions={{ headerShown: false }} />
|
||||
}
|
||||
31
app/(auth)/sign-in.tsx
Normal file
31
app/(auth)/sign-in.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import { SignIn } from '@clerk/clerk-react'
|
||||
import { dark } from '@clerk/themes'
|
||||
import React from 'react'
|
||||
import { StyleSheet, View } from 'react-native'
|
||||
|
||||
export default function SignInScreen() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<SignIn
|
||||
appearance={{
|
||||
theme: dark,
|
||||
variables: {
|
||||
colorPrimary: '#747b83ff',
|
||||
colorBackground: '#25292e',
|
||||
colorInput: '#383e46ff'
|
||||
}
|
||||
}}
|
||||
signUpUrl='/sign-up'
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#25292e',
|
||||
padding: 5,
|
||||
alignItems: 'center'
|
||||
}
|
||||
})
|
||||
31
app/(auth)/sign-up.tsx
Normal file
31
app/(auth)/sign-up.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import { SignUp } from '@clerk/clerk-expo/web'
|
||||
import { dark } from '@clerk/themes'
|
||||
import * as React from 'react'
|
||||
import { StyleSheet, View } from 'react-native'
|
||||
|
||||
export default function SignUpScreen() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<SignUp
|
||||
appearance={{
|
||||
theme: dark,
|
||||
variables: {
|
||||
colorPrimary: '#747b83ff',
|
||||
colorBackground: '#25292e',
|
||||
colorInput: '#383e46ff'
|
||||
}
|
||||
}}
|
||||
signInUrl='/sign-in'
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#25292e',
|
||||
padding: 5,
|
||||
alignItems: 'center'
|
||||
}
|
||||
})
|
||||
@@ -21,7 +21,7 @@ export default function TabLayout() {
|
||||
}}
|
||||
>
|
||||
<Tabs.Screen
|
||||
name='index'
|
||||
name='home'
|
||||
options={{
|
||||
title: 'Home',
|
||||
headerShown: false,
|
||||
@@ -35,7 +35,6 @@ export default function TabLayout() {
|
||||
options={{
|
||||
title: 'Posts',
|
||||
headerShown: false,
|
||||
tabBarItemStyle: { display: isAdmin ? 'flex' : 'none' },
|
||||
tabBarIcon: ({ color, focused }) => (
|
||||
<Ionicons name={focused ? 'rocket-sharp' : 'rocket-outline'} size={24} color={color} />
|
||||
)
|
||||
|
||||
@@ -1,13 +1,25 @@
|
||||
import { useUser } from '@clerk/clerk-react'
|
||||
import React from 'react'
|
||||
import { StyleSheet, TouchableOpacity, View } from 'react-native'
|
||||
import { useSession } from '../ctx'
|
||||
import { Image, StyleSheet, Text, View } from 'react-native'
|
||||
import { SignOutButton } from '../components/SignOutButton'
|
||||
|
||||
export default function PostsScreen() {
|
||||
const { logout } = useSession()
|
||||
|
||||
const user = useUser().user
|
||||
console.log(user?.emailAddresses)
|
||||
return (
|
||||
<View style={styles.wrapper}>
|
||||
<TouchableOpacity onPress={() => logout()}>Logout</TouchableOpacity>
|
||||
<View>
|
||||
<Image></Image>
|
||||
</View>
|
||||
<View style={styles.nameContainer}>
|
||||
<Text style={styles.text}>
|
||||
{user?.firstName} {user?.lastName}
|
||||
</Text>
|
||||
<Text style={styles.text}>{user?.emailAddresses[0].emailAddress}</Text>
|
||||
</View>
|
||||
<View style={styles.buttonLayout}>
|
||||
<SignOutButton></SignOutButton>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
@@ -17,5 +29,16 @@ const styles = StyleSheet.create({
|
||||
flex: 1,
|
||||
backgroundColor: '#25292e',
|
||||
padding: 5
|
||||
},
|
||||
nameContainer: { display: 'flex', alignItems: 'center' },
|
||||
text: {
|
||||
color: 'white',
|
||||
fontSize: 16,
|
||||
marginTop: 6
|
||||
},
|
||||
buttonLayout: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
marginTop: 12
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,29 +1,27 @@
|
||||
import { ClerkProvider, SignedIn, SignedOut } from '@clerk/clerk-expo'
|
||||
import { tokenCache } from '@clerk/clerk-expo/token-cache'
|
||||
import { Stack } from 'expo-router'
|
||||
import { SessionProvider, useSession } from './ctx'
|
||||
import { SplashScreenController } from './splash'
|
||||
import React from 'react'
|
||||
|
||||
export default function Root() {
|
||||
// Set up the auth context and render our layout inside of it.
|
||||
return (
|
||||
<SessionProvider>
|
||||
<SplashScreenController />
|
||||
<ClerkProvider tokenCache={tokenCache}>
|
||||
<RootNavigator />
|
||||
</SessionProvider>
|
||||
</ClerkProvider>
|
||||
)
|
||||
}
|
||||
|
||||
// Separate this into a new component so it can access the SessionProvider context later
|
||||
function RootNavigator() {
|
||||
const { session } = useSession()
|
||||
return (
|
||||
<Stack>
|
||||
<Stack.Protected guard={!!session}>
|
||||
<Stack screenOptions={{ headerShown: false }}>
|
||||
<SignedIn>
|
||||
<Stack.Screen options={{ headerShown: false }} name='(tabs)' />
|
||||
</Stack.Protected>
|
||||
|
||||
<Stack.Protected guard={!session}>
|
||||
<Stack.Screen options={{ headerShown: false }} name='login' />
|
||||
</Stack.Protected>
|
||||
</SignedIn>
|
||||
<SignedOut>
|
||||
<Stack.Screen options={{ headerShown: false }} name='(auth)' />
|
||||
</SignedOut>
|
||||
</Stack>
|
||||
)
|
||||
}
|
||||
|
||||
35
app/components/SignOutButton.tsx
Normal file
35
app/components/SignOutButton.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import { useClerk } from '@clerk/clerk-expo'
|
||||
import * as Linking from 'expo-linking'
|
||||
import { StyleSheet, Text, TouchableOpacity } from 'react-native'
|
||||
|
||||
export const SignOutButton = () => {
|
||||
// Use `useClerk()` to access the `signOut()` function
|
||||
const { signOut } = useClerk()
|
||||
const handleSignOut = async () => {
|
||||
try {
|
||||
await signOut()
|
||||
// Redirect to your desired page
|
||||
Linking.openURL(Linking.createURL('/'))
|
||||
} catch (err) {
|
||||
// See https://clerk.com/docs/custom-flows/error-handling
|
||||
// for more info on error handling
|
||||
console.error(JSON.stringify(err, null, 2))
|
||||
}
|
||||
}
|
||||
return (
|
||||
<TouchableOpacity onPress={handleSignOut} style={styles.button}>
|
||||
<Text>Sign out</Text>
|
||||
</TouchableOpacity>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
button: {
|
||||
width: '40%',
|
||||
height: '5%',
|
||||
backgroundColor: 'rgba(192, 196, 199, 1)',
|
||||
borderRadius: 5,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}
|
||||
})
|
||||
46
app/ctx.tsx
46
app/ctx.tsx
@@ -1,46 +0,0 @@
|
||||
import { createContext, use, type PropsWithChildren } from 'react'
|
||||
import { useStorageState } from './useStorageState'
|
||||
|
||||
const AuthContext = createContext<{
|
||||
login: () => void
|
||||
logout: () => void
|
||||
session?: string | null
|
||||
isLoading: boolean
|
||||
}>({
|
||||
login: () => null,
|
||||
logout: () => null,
|
||||
session: null,
|
||||
isLoading: false
|
||||
})
|
||||
|
||||
// This hook can be used to access the user info.
|
||||
export function useSession() {
|
||||
const value = use(AuthContext)
|
||||
if (!value) {
|
||||
throw new Error('useSession must be wrapped in a <SessionProvider />')
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
export function SessionProvider({ children }: PropsWithChildren) {
|
||||
const [[isLoading, session], setSession] = useStorageState('session')
|
||||
|
||||
return (
|
||||
<AuthContext
|
||||
value={{
|
||||
login: () => {
|
||||
// Perform sign-in logic here
|
||||
setSession('admin')
|
||||
},
|
||||
logout: () => {
|
||||
setSession(null)
|
||||
},
|
||||
session,
|
||||
isLoading
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</AuthContext>
|
||||
)
|
||||
}
|
||||
18
app/index.tsx
Normal file
18
app/index.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import { SignedIn, SignedOut, useUser } from '@clerk/clerk-expo'
|
||||
import { Redirect } from 'expo-router'
|
||||
import { View } from 'react-native'
|
||||
|
||||
export default function Page() {
|
||||
const { user } = useUser()
|
||||
|
||||
return (
|
||||
<View>
|
||||
<SignedIn>
|
||||
<Redirect href={'/home'} />
|
||||
</SignedIn>
|
||||
<SignedOut>
|
||||
<Redirect href={'/(auth)/sign-in'} />
|
||||
</SignedOut>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
@@ -1,12 +1,9 @@
|
||||
import { router } from 'expo-router'
|
||||
import React from 'react'
|
||||
import { StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native'
|
||||
import { useSession } from './ctx'
|
||||
|
||||
export default function LoginScreen() {
|
||||
const [username, setUsername] = React.useState('')
|
||||
const [password, setPassword] = React.useState('')
|
||||
const { login } = useSession()
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
@@ -30,22 +27,19 @@ export default function LoginScreen() {
|
||||
<TouchableOpacity
|
||||
style={styles.button}
|
||||
onPress={() => {
|
||||
login()
|
||||
if (localStorage.getItem('session') === 'success') {
|
||||
router.replace('/')
|
||||
}
|
||||
console.log('test')
|
||||
}}
|
||||
>
|
||||
<Text style={{ color: '#fff', fontWeight: 'bold' }}>Login</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
{/* <TouchableOpacity
|
||||
style={styles.signup}
|
||||
onPress={() => {
|
||||
router.navigate('/signup')
|
||||
}}
|
||||
>
|
||||
<Text style={{ color: '#fff' }}>Sign Up</Text>
|
||||
</TouchableOpacity>
|
||||
</TouchableOpacity> */}
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
import React from 'react'
|
||||
import { StyleSheet, View } from 'react-native'
|
||||
|
||||
export default function SignupScreen() {
|
||||
return <View style={styles.container}></View>
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#25292e',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}
|
||||
})
|
||||
@@ -1,12 +0,0 @@
|
||||
import { SplashScreen } from 'expo-router'
|
||||
import { useSession } from './ctx'
|
||||
|
||||
export function SplashScreenController() {
|
||||
const { isLoading } = useSession()
|
||||
|
||||
if (!isLoading) {
|
||||
SplashScreen.hideAsync()
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
Reference in New Issue
Block a user