diff --git a/src/app/auth/_layout.tsx b/src/app/auth/_layout.tsx
index 0578a39c..cf7d8349 100644
--- a/src/app/auth/_layout.tsx
+++ b/src/app/auth/_layout.tsx
@@ -5,6 +5,7 @@ function StackLayout() {
+
);
diff --git a/src/app/auth/login.tsx b/src/app/auth/login.tsx
new file mode 100644
index 00000000..4015aabd
--- /dev/null
+++ b/src/app/auth/login.tsx
@@ -0,0 +1,62 @@
+import React, { useState } from 'react';
+import { Redirect, Link } from 'expo-router';
+import { Alert, View } from 'react-native';
+import { Button, Input } from 'react-native-elements';
+import { useSession } from '../../utils/AuthContext';
+import globalStyles from '../../styles/globalStyles';
+
+function LoginScreen() {
+ const sessionHandler = useSession();
+ const [email, setEmail] = useState('');
+ const [password, setPassword] = useState('');
+ const [loading, setLoading] = useState(false);
+
+ if (sessionHandler.session) {
+ return ;
+ }
+
+ const signInWithEmail = async () => {
+ setLoading(true);
+ const { error, data } = await sessionHandler.signInWithEmail(
+ email,
+ password,
+ );
+
+ if (error) Alert.alert(error.message);
+ setLoading(false);
+ };
+
+ return (
+
+
+ setEmail(text)}
+ value={email}
+ placeholder="email@address.com"
+ autoCapitalize="none"
+ />
+
+
+ setPassword(text)}
+ value={password}
+ secureTextEntry
+ placeholder="Password"
+ autoCapitalize="none"
+ />
+
+
+ Don't have an account? Sign Up
+
+
+
+
+
+ );
+}
+
+export default LoginScreen;
diff --git a/src/app/auth/onboarding.tsx b/src/app/auth/onboarding.tsx
index 727a807b..78b16b02 100644
--- a/src/app/auth/onboarding.tsx
+++ b/src/app/auth/onboarding.tsx
@@ -1,14 +1,161 @@
-import { View } from 'react-native';
-
-import Account from '../../components/Account';
-import Login from '../../components/Login';
+import { useState, useEffect } from 'react';
+import { View, Alert, ScrollView, Platform } from 'react-native';
+import { Button, Input } from 'react-native-elements';
+import DateTimePicker from '@react-native-community/datetimepicker';
+import { Redirect, router } from 'expo-router';
+import supabase from '../../utils/supabase';
+import UserStringInput from '../../components/UserStringInput';
import { useSession } from '../../utils/AuthContext';
+import globalStyles from '../../styles/globalStyles';
function OnboardingScreen() {
- const { session } = useSession();
+ const { session, signOut } = useSession();
+ const [loading, setLoading] = useState(true);
+ const [firstName, setFirstName] = useState('');
+ const [lastName, setLastName] = useState('');
+ const [birthday, setBirthday] = useState(new Date());
+ const [gender, setGender] = useState('');
+ const [raceEthnicity, setRaceEthnicity] = useState('');
+ const [showDatePicker, setShowDatePicker] = useState(Platform.OS === 'ios');
+
+ const getProfile = async () => {
+ try {
+ setLoading(true);
+ if (!session?.user) throw new Error('No user on the session!');
+
+ const { data, error, status } = await supabase
+ .from('profiles')
+ .select(`first_name, last_name, birthday, gender, race_ethnicity`)
+ .eq('user_id', session?.user.id)
+ .single();
+
+ if (error && status !== 406) {
+ throw error;
+ }
+
+ if (data) {
+ setFirstName(data.first_name || firstName);
+ setLastName(data.last_name || lastName);
+ setBirthday(new Date(data.birthday) || birthday);
+ setGender(data.gender || gender);
+ setRaceEthnicity(data.race_ethnicity || raceEthnicity);
+ }
+ } catch (error) {
+ if (error instanceof Error) {
+ Alert.alert(`Get profile error: ${error.message}`);
+ }
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ useEffect(() => {
+ if (session) getProfile();
+ }, [session]);
+
+ const updateProfileAndGoHome = async () => {
+ try {
+ setLoading(true);
+ if (!session?.user) throw new Error('No user on the session!');
+
+ // Only update values that are not blank
+ const updates = {
+ ...(firstName && { first_name: firstName }),
+ ...(lastName && { last_name: lastName }),
+ ...(gender && { gender }),
+ ...(raceEthnicity && { race_ethnicity: raceEthnicity }),
+ ...(birthday && { birthday }),
+ };
+
+ // Check if user exists
+ const { count } = await supabase
+ .from('profiles')
+ .select(`*`, { count: 'exact' })
+ .eq('user_id', session?.user.id);
+
+ if (count && count >= 1) {
+ // Update user if they exist
+ const { error } = await supabase
+ .from('profiles')
+ .update(updates)
+ .eq('user_id', session?.user.id)
+ .select('*');
+
+ if (error) throw error;
+ } else {
+ // Create user if they don't exist
+ const { error } = await supabase.from('profiles').insert(updates);
+
+ if (error) throw error;
+ }
+
+ Alert.alert('Succesfully updated user!');
+ router.replace('/home');
+ } catch (error) {
+ if (error instanceof Error) {
+ Alert.alert(error.message);
+ }
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ if (!session) {
+ return ;
+ }
return (
- {session?.user ? : }
+
+
+
+
+
+
+
+
+
+ {Platform.OS !== 'ios' && (
+
);
}
diff --git a/src/app/auth/signup.tsx b/src/app/auth/signup.tsx
index da5094ab..94db3d4f 100644
--- a/src/app/auth/signup.tsx
+++ b/src/app/auth/signup.tsx
@@ -1,14 +1,86 @@
-import { View } from 'react-native';
-
-import Account from '../../components/Account';
-import Login from '../../components/Login';
+import React, { useEffect, useState } from 'react';
+import { Redirect, Link, router } from 'expo-router';
+import { Alert, View, Text } from 'react-native';
+import { Button, Input } from 'react-native-elements';
import { useSession } from '../../utils/AuthContext';
+import globalStyles from '../../styles/globalStyles';
function SignUpScreen() {
- const { session } = useSession();
+ const { session, signUp, signInWithEmail } = useSession();
+
+ const [email, setEmail] = useState('');
+ const [password, setPassword] = useState('');
+ const [loading, setLoading] = useState(false);
+ const [signedUp, setSignedUp] = useState(false);
+
+ if (session) {
+ return ;
+ }
+
+ const signIn = async () => {
+ setLoading(true);
+ const { error } = await signInWithEmail(email, password);
+
+ if (error) Alert.alert(error.message);
+ else router.replace('/auth/onboarding');
+
+ setLoading(false);
+ };
+
+ const signUpWithEmail = async () => {
+ setLoading(true);
+ const { error } = await signUp(email, password);
+
+ if (error) Alert.alert(error.message);
+ else {
+ Alert.alert(
+ 'Please follow the instructions in your email to verify your account, then login',
+ );
+ setSignedUp(true);
+ }
+ setLoading(false);
+ };
return (
- {session?.user ? : }
+
+
+ setEmail(text)}
+ value={email}
+ placeholder="email@address.com"
+ autoCapitalize="none"
+ />
+
+
+ setPassword(text)}
+ value={password}
+ secureTextEntry
+ placeholder="Password"
+ autoCapitalize="none"
+ />
+
+ {signedUp ? (
+
+
+
+ ) : (
+ <>
+ Already have an account? Log In
+
+
+
+ >
+ )}
+
);
}
diff --git a/src/app/index.tsx b/src/app/index.tsx
index 91b8d926..d834a1a6 100644
--- a/src/app/index.tsx
+++ b/src/app/index.tsx
@@ -1,7 +1,11 @@
import { Redirect } from 'expo-router';
+import { useSession } from '../utils/AuthContext';
function StartPage() {
- return ;
+ const { session } = useSession();
+
+ if (!session) return ;
+ return ;
}
export default StartPage;
diff --git a/src/app/settings.tsx b/src/app/settings.tsx
index 8086aa35..9528acc6 100644
--- a/src/app/settings.tsx
+++ b/src/app/settings.tsx
@@ -1,12 +1,24 @@
-import { Text } from 'react-native';
+import { Redirect, router } from 'expo-router';
+import { Text, View } from 'react-native';
+import { Button } from 'react-native-elements';
import { SafeAreaView } from 'react-native-safe-area-context';
-
+import { useSession } from '../utils/AuthContext';
import globalStyles from '../styles/globalStyles';
function SettingsScreen() {
+ const { session, signOut } = useSession();
+
+ if (!session) return ;
return (
Settings
+
+ router.push('/auth/onboarding')}
+ />
+
+
);
}
diff --git a/src/components/Account.tsx b/src/components/Account.tsx
deleted file mode 100644
index 4c16c3c6..00000000
--- a/src/components/Account.tsx
+++ /dev/null
@@ -1,177 +0,0 @@
-import DateTimePicker from '@react-native-community/datetimepicker';
-import { useState, useEffect } from 'react';
-import { StyleSheet, View, Alert, ScrollView, Platform } from 'react-native';
-import { Button, Input } from 'react-native-elements';
-
-import UserStringInput from './UserStringInput';
-import { useSession } from '../utils/AuthContext';
-import supabase from '../utils/supabase';
-
-const styles = StyleSheet.create({
- container: {
- marginTop: 40,
- padding: 12,
- },
- verticallySpaced: {
- paddingTop: 4,
- paddingBottom: 4,
- alignSelf: 'stretch',
- },
- mt20: {
- marginTop: 20,
- },
-});
-
-export default function Account() {
- const { session, signOut } = useSession();
-
- const [loading, setLoading] = useState(true);
- const [firstName, setFirstName] = useState('');
- const [lastName, setLastName] = useState('');
- const [birthday, setBirthday] = useState(new Date());
- const [gender, setGender] = useState('');
- const [raceEthnicity, setRaceEthnicity] = useState('');
- const [showDatePicker, setShowDatePicker] = useState(Platform.OS === 'ios');
-
- const getProfile = async () => {
- try {
- setLoading(true);
- if (!session?.user) throw new Error('No user on the session!');
-
- const { data, error, status } = await supabase
- .from('profiles')
- .select(`first_name, last_name, birthday, gender, race_ethnicity`)
- .eq('user_id', session?.user.id)
- .single();
-
- if (error && status !== 406) {
- console.warn(error);
- throw new Error(error.message);
- }
-
- if (data) {
- setFirstName(data.first_name || firstName);
- setLastName(data.last_name || lastName);
- setBirthday(new Date(data.birthday) || birthday);
- setGender(data.gender || gender);
- setRaceEthnicity(data.race_ethnicity || raceEthnicity);
- }
- } catch (error) {
- if (error instanceof Error) {
- Alert.alert(`Get profile error: ${error.message}`);
- }
- } finally {
- setLoading(false);
- }
- };
-
- useEffect(() => {
- if (session) getProfile();
- }, [session]);
-
- const updateProfile = async () => {
- try {
- setLoading(true);
- if (!session?.user) throw new Error('No user on the session!');
-
- // Only update values that are not blank
- const updates = {
- ...(firstName && { first_name: firstName }),
- ...(lastName && { last_name: lastName }),
- ...(gender && { gender }),
- ...(raceEthnicity && { race_ethnicity: raceEthnicity }),
- ...(birthday && { birthday }),
- };
-
- // Check if user exists
- const { count } = await supabase
- .from('profiles')
- .select(`*`, { count: 'exact' })
- .eq('user_id', session?.user.id);
-
- if (count && count >= 1) {
- // Update user if they exist
- const { error } = await supabase
- .from('profiles')
- .update(updates)
- .eq('user_id', session?.user.id)
- .select('*');
-
- if (error) {
- console.warn(error);
- throw new Error(error.message);
- }
- } else {
- // Create user if they don't exist
- const { error } = await supabase.from('profiles').insert(updates);
-
- if (error) {
- console.warn(error);
- throw new Error(error.message);
- }
- }
-
- Alert.alert('Succesfully updated user!');
- } catch (error) {
- if (error instanceof Error) {
- Alert.alert(error.message);
- }
- } finally {
- setLoading(false);
- }
- };
-
- return (
-
-
-
-
-
-
-
-
-
- {Platform.OS !== 'ios' && (
- setShowDatePicker(true)}
- />
- )}
- {showDatePicker && (
- {
- setShowDatePicker(Platform.OS === 'ios');
- if (date.nativeEvent.timestamp) {
- setBirthday(new Date(date.nativeEvent.timestamp));
- }
- }}
- />
- )}
-
-
-
-
-
-
-
- );
-}
diff --git a/src/components/Login.tsx b/src/components/Login.tsx
deleted file mode 100644
index 9a757f59..00000000
--- a/src/components/Login.tsx
+++ /dev/null
@@ -1,82 +0,0 @@
-import React, { useState } from 'react';
-import { Alert, StyleSheet, View } from 'react-native';
-import { Button, Input } from 'react-native-elements';
-
-import { useSession } from '../utils/AuthContext';
-
-const styles = StyleSheet.create({
- container: {
- marginTop: 40,
- padding: 12,
- },
- verticallySpaced: {
- paddingTop: 4,
- paddingBottom: 4,
- alignSelf: 'stretch',
- },
- mt20: {
- marginTop: 20,
- },
-});
-
-export default function Login() {
- const sessionHandler = useSession();
- const [email, setEmail] = useState('');
- const [password, setPassword] = useState('');
- const [loading, setLoading] = useState(false);
-
- const signInWithEmail = async () => {
- setLoading(true);
- const { error } = await sessionHandler.signInWithEmail(email, password);
-
- if (error) Alert.alert(error.message);
- setLoading(false);
- };
-
- const signUpWithEmail = async () => {
- setLoading(true);
- const { error } = await sessionHandler.signUp(email, password);
-
- if (error) {
- Alert.alert(error.message);
- console.error(error);
- } else {
- Alert.alert(
- 'Please follow the directions in the confirmation email to activate your account.',
- );
- }
- setLoading(false);
- };
-
- return (
-
-
- setEmail(text)}
- value={email}
- placeholder="email@address.com"
- autoCapitalize="none"
- />
-
-
- setPassword(text)}
- value={password}
- secureTextEntry
- placeholder="Password"
- autoCapitalize="none"
- />
-
-
-
-
-
-
-
-
- );
-}
diff --git a/src/styles/globalStyles.ts b/src/styles/globalStyles.ts
index 2a4e3ad7..cbe46541 100644
--- a/src/styles/globalStyles.ts
+++ b/src/styles/globalStyles.ts
@@ -9,6 +9,10 @@ export default StyleSheet.create({
paddingLeft: 24,
paddingRight: 24,
},
+ auth_container: {
+ marginTop: 40,
+ padding: 12,
+ },
h1: {
// fontFamily: 'DMSans-Bold',
fontSize: 50,
@@ -59,4 +63,12 @@ export default StyleSheet.create({
textAlign: 'left',
color: 'black',
},
+ verticallySpaced: {
+ paddingTop: 4,
+ paddingBottom: 4,
+ alignSelf: 'stretch',
+ },
+ mt20: {
+ marginTop: 20,
+ },
});
diff --git a/src/utils/AuthContext.tsx b/src/utils/AuthContext.tsx
index 14ff3355..c3081d0a 100644
--- a/src/utils/AuthContext.tsx
+++ b/src/utils/AuthContext.tsx
@@ -44,7 +44,7 @@ export function AuthContextProvider({
setSession(newSession);
});
- supabase.auth.onAuthStateChange((_event, newSession) => {
+ supabase.auth.onAuthStateChange((event, newSession) => {
setSession(newSession);
});
}, []);
@@ -58,11 +58,13 @@ export function AuthContextProvider({
email,
password,
}); // will trigger the use effect to update the session
+
const signUp = async (email: string, password: string) =>
supabase.auth.signUp({
email,
password,
}); // will trigger the use effect to update the session
+
const signOut = () => {
supabase.auth.signOut();
setSession(null);