clerk sign in and sign up login setup
This commit is contained in:
committed by
GitHub
parent
640961eeec
commit
a5cabfe1a1
@@ -65,7 +65,7 @@ const SignIn = () => {
|
|||||||
className="mt-6"
|
className="mt-6"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<OAuth />
|
<OAuth title="Sign in with Google" />
|
||||||
|
|
||||||
<Link
|
<Link
|
||||||
href="/sign-up"
|
href="/sign-up"
|
||||||
|
|||||||
+64
-2
@@ -1,3 +1,4 @@
|
|||||||
|
import { useSignUp } from "@clerk/clerk-expo";
|
||||||
import { Link } from "expo-router";
|
import { Link } from "expo-router";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Image, ScrollView, Text, View } from "react-native";
|
import { Image, ScrollView, Text, View } from "react-native";
|
||||||
@@ -8,13 +9,74 @@ import { OAuth } from "@/components/oauth";
|
|||||||
import { icons, images } from "@/constants";
|
import { icons, images } from "@/constants";
|
||||||
|
|
||||||
const SignUp = () => {
|
const SignUp = () => {
|
||||||
|
const { isLoaded, signUp, setActive } = useSignUp();
|
||||||
|
|
||||||
const [form, setForm] = useState({
|
const [form, setForm] = useState({
|
||||||
name: "",
|
name: "",
|
||||||
email: "",
|
email: "",
|
||||||
password: "",
|
password: "",
|
||||||
});
|
});
|
||||||
|
|
||||||
const onSignUpPress = async () => {};
|
const [verification, setVerification] = useState({
|
||||||
|
state: "default",
|
||||||
|
error: "",
|
||||||
|
code: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSignUpPress = async () => {
|
||||||
|
if (!isLoaded) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await signUp.create({
|
||||||
|
emailAddress: form.email,
|
||||||
|
password: form.password,
|
||||||
|
firstName: form.name,
|
||||||
|
});
|
||||||
|
|
||||||
|
await signUp.prepareEmailAddressVerification({ strategy: "email_code" });
|
||||||
|
|
||||||
|
setVerification((prevVerification) => ({
|
||||||
|
...prevVerification,
|
||||||
|
state: "pending",
|
||||||
|
}));
|
||||||
|
} catch (err: any) {
|
||||||
|
console.error(JSON.stringify(err, null, 2));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onPressVerify = async () => {
|
||||||
|
if (!isLoaded) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const completeSignUp = await signUp.attemptEmailAddressVerification({
|
||||||
|
code: verification.code,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (completeSignUp.status === "complete") {
|
||||||
|
// TODO: Create a database user
|
||||||
|
|
||||||
|
await setActive({ session: completeSignUp.createdSessionId });
|
||||||
|
setVerification((prevVerification) => ({
|
||||||
|
...prevVerification,
|
||||||
|
state: "success",
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
setVerification((prevVerification) => ({
|
||||||
|
...prevVerification,
|
||||||
|
error: "Verification failed.",
|
||||||
|
state: "failed",
|
||||||
|
}));
|
||||||
|
console.error(JSON.stringify(completeSignUp, null, 2));
|
||||||
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
console.error(JSON.stringify(err, null, 2));
|
||||||
|
setVerification((prevVerification) => ({
|
||||||
|
...prevVerification,
|
||||||
|
error: err?.errors[0]?.longMessage,
|
||||||
|
state: "failed",
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollView className="flex-1 bg-white">
|
<ScrollView className="flex-1 bg-white">
|
||||||
@@ -79,7 +141,7 @@ const SignUp = () => {
|
|||||||
className="mt-6"
|
className="mt-6"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<OAuth />
|
<OAuth title="Sign up with Google" />
|
||||||
|
|
||||||
<Link
|
<Link
|
||||||
href="/sign-in"
|
href="/sign-in"
|
||||||
|
|||||||
@@ -1,10 +1,24 @@
|
|||||||
|
import { SignedIn, SignedOut, useUser } from "@clerk/clerk-expo";
|
||||||
|
import { Link } from "expo-router";
|
||||||
import { Text } from "react-native";
|
import { Text } from "react-native";
|
||||||
import { SafeAreaView } from "react-native-safe-area-context";
|
import { SafeAreaView } from "react-native-safe-area-context";
|
||||||
|
|
||||||
const Home = () => {
|
const Home = () => {
|
||||||
|
const { user } = useUser();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaView>
|
<SafeAreaView>
|
||||||
<Text>Home</Text>
|
<SignedIn>
|
||||||
|
<Text>Hello {user?.emailAddresses[0].emailAddress}</Text>
|
||||||
|
</SignedIn>
|
||||||
|
<SignedOut>
|
||||||
|
<Link href="/sign-in">
|
||||||
|
<Text>Sign In</Text>
|
||||||
|
</Link>
|
||||||
|
<Link href="/sign-up">
|
||||||
|
<Text>Sign Up</Text>
|
||||||
|
</Link>
|
||||||
|
</SignedOut>
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { ClerkProvider, ClerkLoaded } from "@clerk/clerk-expo";
|
||||||
import { useFonts } from "expo-font";
|
import { useFonts } from "expo-font";
|
||||||
import { Stack } from "expo-router";
|
import { Stack } from "expo-router";
|
||||||
import * as SplashScreen from "expo-splash-screen";
|
import * as SplashScreen from "expo-splash-screen";
|
||||||
@@ -28,12 +29,20 @@ const RootLayout = () => {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const publishableKey = process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY!;
|
||||||
|
|
||||||
|
if (!publishableKey) throw new Error("Missing Clerk Publishable Key.");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<ClerkProvider publishableKey={publishableKey}>
|
||||||
|
<ClerkLoaded>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Stack.Screen name="index" options={{ headerShown: false }} />
|
<Stack.Screen name="index" options={{ headerShown: false }} />
|
||||||
<Stack.Screen name="(root)" options={{ headerShown: false }} />
|
<Stack.Screen name="(root)" options={{ headerShown: false }} />
|
||||||
<Stack.Screen name="(auth)" options={{ headerShown: false }} />
|
<Stack.Screen name="(auth)" options={{ headerShown: false }} />
|
||||||
</Stack>
|
</Stack>
|
||||||
|
</ClerkLoaded>
|
||||||
|
</ClerkProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
|
import { useAuth } from "@clerk/clerk-expo";
|
||||||
import { Redirect } from "expo-router";
|
import { Redirect } from "expo-router";
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
|
const { isSignedIn } = useAuth();
|
||||||
|
|
||||||
|
if (isSignedIn) return <Redirect href="/(root)/(tabs)/home" />;
|
||||||
|
|
||||||
return <Redirect href="/(auth)/welcome" />;
|
return <Redirect href="/(auth)/welcome" />;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,11 @@ import { icons } from "@/constants";
|
|||||||
|
|
||||||
import { CustomButton } from "./custom-button";
|
import { CustomButton } from "./custom-button";
|
||||||
|
|
||||||
export const OAuth = () => {
|
type OAuthProps = {
|
||||||
|
title: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const OAuth = ({ title }: OAuthProps) => {
|
||||||
const handleGoogleSignIn = () => {};
|
const handleGoogleSignIn = () => {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -18,7 +22,7 @@ export const OAuth = () => {
|
|||||||
</View>
|
</View>
|
||||||
|
|
||||||
<CustomButton
|
<CustomButton
|
||||||
title="Log in with Google"
|
title={title}
|
||||||
className="mt-5 w-full shadow-none"
|
className="mt-5 w-full shadow-none"
|
||||||
iconLeft={() => (
|
iconLeft={() => (
|
||||||
<Image
|
<Image
|
||||||
|
|||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
import * as SecureStore from "expo-secure-store";
|
||||||
|
|
||||||
|
export interface TokenCache {
|
||||||
|
getToken: (key: string) => Promise<string | undefined | null>;
|
||||||
|
saveToken: (key: string, token: string) => Promise<void>;
|
||||||
|
clearToken?: (key: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const tokenCache = {
|
||||||
|
async getToken(key: string) {
|
||||||
|
try {
|
||||||
|
const item = await SecureStore.getItemAsync(key);
|
||||||
|
if (item) {
|
||||||
|
console.log(`${key} was used 🔐 \n`);
|
||||||
|
} else {
|
||||||
|
console.log("No values stored under key: " + key);
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("SecureStore get item error: ", error);
|
||||||
|
await SecureStore.deleteItemAsync(key);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async saveToken(key: string, value: string) {
|
||||||
|
try {
|
||||||
|
return SecureStore.setItemAsync(key, value);
|
||||||
|
} catch (err) {
|
||||||
|
console.error("TOKEN_CACHE: ", err);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user