finger

finger
git clone https://git.prime8.dev/finger.git
Log | Files | Refs | README | LICENSE

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 }