-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[auth] Implement email account creation (#10)
* Add components from tutorials * Add profile columns to update page * Update supabase data working * Only update non-blank entries * Run eslint fix * Fix eslint errors * Fix tsc errors * Fix trivial review changes * Add components from tutorials * Add profile columns to update page * Update supabase data working * Only update non-blank entries * Run eslint fix * Fix eslint errors * Fix tsc errors * Fix trivial review changes * Downgrade ts to be compatible with deps * Add components from tutorials * Add profile columns to update page * Update supabase data working * Only update non-blank entries * Run eslint fix * Fix eslint errors * Fix trivial review changes * Add components from tutorials * Add profile columns to update page * Update supabase data working * Only update non-blank entries * Run eslint fix * Fix eslint errors * Fixes after merge :( * Fix eslint errors * Fix routing for sign up/in * Downgrade ts * Fix andriod date taking up the screen * Fix build * Downgrade ts * Fix android date issue * Fix package-lock.jsonO --------- Co-authored-by: Aditya Pawar <[email protected]>
- Loading branch information
1 parent
d0a7f60
commit e30c936
Showing
10 changed files
with
974 additions
and
631 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
EXPO_PUBLIC_SUPABASE_URL = | ||
EXPO_PUBLIC_SUPABASE_ANON_KEY = |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
import { useState, useEffect } from 'react'; | ||
import { StyleSheet, View, Alert, ScrollView, Platform } from 'react-native'; | ||
import { Button, Input } from 'react-native-elements'; | ||
import { Session } from '@supabase/supabase-js'; | ||
import DateTimePicker from '@react-native-community/datetimepicker'; | ||
import supabase from '../utils/supabase'; | ||
import UserStringInput from './UserStringInput'; | ||
|
||
const styles = StyleSheet.create({ | ||
container: { | ||
marginTop: 40, | ||
padding: 12, | ||
}, | ||
verticallySpaced: { | ||
paddingTop: 4, | ||
paddingBottom: 4, | ||
alignSelf: 'stretch', | ||
}, | ||
mt20: { | ||
marginTop: 20, | ||
}, | ||
}); | ||
|
||
export default function Account({ session }: { session: Session }) { | ||
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 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) 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!'); | ||
} catch (error) { | ||
if (error instanceof Error) { | ||
Alert.alert(error.message); | ||
} | ||
} finally { | ||
setLoading(false); | ||
} | ||
}; | ||
|
||
return ( | ||
<ScrollView style={styles.container}> | ||
<View style={[styles.verticallySpaced, styles.mt20]}> | ||
<Input label="Email" value={session?.user?.email} disabled /> | ||
</View> | ||
<UserStringInput | ||
label="First Name" | ||
value={firstName} | ||
onChange={setFirstName} | ||
/> | ||
<UserStringInput | ||
label="Last Name" | ||
value={lastName} | ||
onChange={setLastName} | ||
/> | ||
<UserStringInput label="Gender" value={gender} onChange={setGender} /> | ||
<UserStringInput | ||
label="Race/Ethnicity" | ||
value={raceEthnicity} | ||
onChange={setRaceEthnicity} | ||
/> | ||
|
||
{Platform.OS !== 'ios' && ( | ||
<Button | ||
title="Change Birthday" | ||
onPress={() => setShowDatePicker(true)} | ||
/> | ||
)} | ||
{showDatePicker && ( | ||
<DateTimePicker | ||
testID="dateTimePicker" | ||
value={birthday} | ||
mode="date" | ||
onChange={date => { | ||
setShowDatePicker(Platform.OS === 'ios'); | ||
if (date.nativeEvent.timestamp) { | ||
setBirthday(new Date(date.nativeEvent.timestamp)); | ||
} | ||
}} | ||
/> | ||
)} | ||
<View style={[styles.verticallySpaced, styles.mt20]}> | ||
<Button | ||
title={loading ? 'Loading ...' : 'Update'} | ||
onPress={updateProfile} | ||
disabled={loading} | ||
/> | ||
</View> | ||
<View style={styles.verticallySpaced}> | ||
<Button title="Sign Out" onPress={() => supabase.auth.signOut()} /> | ||
</View> | ||
</ScrollView> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import React, { useState } from 'react'; | ||
import { Alert, StyleSheet, View } from 'react-native'; | ||
import { Button, Input } from 'react-native-elements'; | ||
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 Login() { | ||
const [email, setEmail] = useState(''); | ||
const [password, setPassword] = useState(''); | ||
const [loading, setLoading] = useState(false); | ||
|
||
const signInWithEmail = async () => { | ||
setLoading(true); | ||
const { error } = await supabase.auth.signInWithPassword({ | ||
email, | ||
password, | ||
}); | ||
|
||
if (error) Alert.alert(error.message); | ||
setLoading(false); | ||
}; | ||
|
||
const signUpWithEmail = async () => { | ||
setLoading(true); | ||
const { error } = await supabase.auth.signUp({ | ||
email, | ||
password, | ||
}); | ||
|
||
if (error) Alert.alert(error.message); | ||
console.error(error); | ||
setLoading(false); | ||
}; | ||
|
||
return ( | ||
<View style={styles.container}> | ||
<View style={[styles.verticallySpaced, styles.mt20]}> | ||
<Input | ||
label="Email" | ||
leftIcon={{ type: 'font-awesome', name: 'envelope' }} | ||
onChangeText={text => setEmail(text)} | ||
value={email} | ||
placeholder="[email protected]" | ||
autoCapitalize="none" | ||
/> | ||
</View> | ||
<View style={styles.verticallySpaced}> | ||
<Input | ||
label="Password" | ||
leftIcon={{ type: 'font-awesome', name: 'lock' }} | ||
onChangeText={text => setPassword(text)} | ||
value={password} | ||
secureTextEntry | ||
placeholder="Password" | ||
autoCapitalize="none" | ||
/> | ||
</View> | ||
<View style={[styles.verticallySpaced, styles.mt20]}> | ||
<Button title="Sign in" disabled={loading} onPress={signInWithEmail} /> | ||
</View> | ||
<View style={styles.verticallySpaced}> | ||
<Button title="Sign up" disabled={loading} onPress={signUpWithEmail} /> | ||
</View> | ||
</View> | ||
); | ||
} |
Oops, something went wrong.