auth.tsx (3497B)
1 import { useState } from "react"; 2 import { Alert, Pressable } from "react-native"; 3 import { supabase } from "@/lib/supabase"; 4 import { Button, Input, XStack, YStack, Text } from "tamagui"; 5 import { router } from "expo-router"; 6 7 export default function Auth() { 8 const [mode, setMode] = useState<"signIn" | "signUp">("signIn"); 9 const [email, setEmail] = useState(""); 10 const [password, setPassword] = useState(""); 11 const [confirmPassword, setConfirmPassword] = useState(""); 12 const [loading, setLoading] = useState(false); 13 14 function toggleMode() { 15 setMode((m) => (m === "signIn" ? "signUp" : "signIn")); 16 } 17 18 async function handleAuth() { 19 if (!email || !password) { 20 Alert.alert("Please enter your email and password"); 21 return; 22 } 23 24 if (mode === "signUp" && password !== confirmPassword) { 25 Alert.alert("Passwords do not match"); 26 return; 27 } 28 29 setLoading(true); 30 31 try { 32 if (mode === "signIn") { 33 const { error } = await supabase.auth.signInWithPassword({ 34 email, 35 password, 36 }); 37 if (error) throw error; 38 } else { 39 const { data, error } = await supabase.auth.signUp({ 40 email, 41 password, 42 }); 43 if (error) throw error; 44 45 if (!data?.user) { 46 Alert.alert( 47 "Please check your inbox to verify your email before signing in.", 48 ); 49 } 50 } 51 52 router.replace("/home"); 53 } catch (err: any) { 54 Alert.alert(err.message ?? "Something went wrong, please try again."); 55 } finally { 56 setLoading(false); 57 } 58 } 59 60 return ( 61 <YStack 62 flex={1} 63 alignItems="center" 64 justifyContent="center" 65 padding={24} 66 minHeight="100vh" 67 width="100%" 68 backgroundColor="$background" 69 > 70 <YStack 71 width={320} 72 alignItems="center" 73 justifyContent="center" 74 padding={24} 75 gap={12} 76 > 77 <Text fontSize={24} fontWeight="600"> 78 {mode === "signIn" ? "Welcome back" : "Create an account"} 79 </Text> 80 81 <Input 82 placeholder="email@address.com" 83 width={260} 84 value={email} 85 onChangeText={setEmail} 86 autoCapitalize="none" 87 keyboardType="email-address" 88 /> 89 90 <Input 91 placeholder="Password" 92 width={260} 93 value={password} 94 onChangeText={setPassword} 95 secureTextEntry 96 autoCapitalize="none" 97 /> 98 99 {mode === "signUp" && ( 100 <Input 101 placeholder="Confirm Password" 102 width={260} 103 value={confirmPassword} 104 onChangeText={setConfirmPassword} 105 secureTextEntry 106 autoCapitalize="none" 107 /> 108 )} 109 110 <Button 111 width={260} 112 disabled={loading} 113 onPress={handleAuth} 114 marginTop={8} 115 > 116 {loading ? "Loading…" : mode === "signIn" ? "Sign In" : "Sign Up"} 117 </Button> 118 119 <XStack marginTop={12} alignItems="center" gap={6}> 120 <Text> 121 {mode === "signIn" 122 ? "Don't have an account?" 123 : "Already have an account?"} 124 </Text> 125 <Pressable onPress={toggleMode} disabled={loading}> 126 <Text color="$blue10" fontWeight="600"> 127 {mode === "signIn" ? "Sign Up" : "Sign In"} 128 </Text> 129 </Pressable> 130 </XStack> 131 </YStack> 132 </YStack> 133 ); 134 }