feat: Implemented log in, sign up and sign out
This commit is contained in:
@ -1,18 +1,64 @@
|
||||
import React from 'react';
|
||||
import { NavigationContainer } from '@react-navigation/native';
|
||||
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
||||
import React, {useEffect} from 'react';
|
||||
import {Text, Pressable} from 'react-native';
|
||||
import {
|
||||
NavigationContainer,
|
||||
useNavigationContainerRef,
|
||||
} from '@react-navigation/native';
|
||||
import {createNativeStackNavigator} from '@react-navigation/native-stack';
|
||||
import SignIn from './screens/SignIn';
|
||||
import useLoggedIn from './hooks/useLoggedIn';
|
||||
import SignUp from './screens/SignUp';
|
||||
import Buckets from './screens/Buckets';
|
||||
import Settings from './screens/Settings';
|
||||
|
||||
const Stack = createNativeStackNavigator();
|
||||
|
||||
const Navigation = () => {
|
||||
const [isInitializing, user] = useLoggedIn();
|
||||
|
||||
console.log('[user]', user);
|
||||
|
||||
if (isInitializing) {
|
||||
return <Text>Loading...</Text>;
|
||||
}
|
||||
|
||||
return (
|
||||
<NavigationContainer>
|
||||
<Stack.Navigator>
|
||||
<Stack.Screen name="SignIn" component={SignIn} />
|
||||
<Stack.Navigator initialRouteName={!!user ? 'Buckets' : 'SignIn'}>
|
||||
<Stack.Screen
|
||||
name="SignIn"
|
||||
component={SignIn}
|
||||
options={{title: 'Sign In'}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="SignUp"
|
||||
component={SignUp}
|
||||
options={{title: 'Sign Up'}}
|
||||
/>
|
||||
{!!user ? (
|
||||
<React.Fragment>
|
||||
<Stack.Screen
|
||||
name="Buckets"
|
||||
component={Buckets}
|
||||
options={({navigation}) => ({
|
||||
title: 'S3 Buckets',
|
||||
headerRight: () => (
|
||||
<Pressable onPress={() => navigation.navigate('Settings')}>
|
||||
<Text style={{fontSize: 24, color: '#000000'}}>⚙</Text>
|
||||
</Pressable>
|
||||
),
|
||||
})}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="Settings"
|
||||
component={Settings}
|
||||
options={{title: 'Settings'}}
|
||||
/>
|
||||
</React.Fragment>
|
||||
) : null}
|
||||
</Stack.Navigator>
|
||||
</NavigationContainer>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default Navigation;
|
||||
export default Navigation;
|
||||
|
24
src/hooks/useLoggedIn.js
Normal file
24
src/hooks/useLoggedIn.js
Normal file
@ -0,0 +1,24 @@
|
||||
import {useState, useCallback, useEffect} from 'react';
|
||||
import auth from '@react-native-firebase/auth';
|
||||
|
||||
const useLoggedIn = () => {
|
||||
const [isInit, setIsInit] = useState(true);
|
||||
const [user, setUser] = useState(null);
|
||||
|
||||
const onChange = useCallback(
|
||||
user => {
|
||||
setUser(user);
|
||||
setIsInit(false);
|
||||
},
|
||||
[setUser, setIsInit],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribe = auth().onAuthStateChanged(onChange);
|
||||
return unsubscribe;
|
||||
}, []);
|
||||
|
||||
return [isInit, user];
|
||||
};
|
||||
|
||||
export default useLoggedIn;
|
21
src/hooks/useLogin.js
Normal file
21
src/hooks/useLogin.js
Normal file
@ -0,0 +1,21 @@
|
||||
import {useCallback} from 'react';
|
||||
import {ToastAndroid} from 'react-native';
|
||||
import auth from '@react-native-firebase/auth';
|
||||
|
||||
const useLogin = () => {
|
||||
const logIn = useCallback((user, pass) => {
|
||||
return auth()
|
||||
.signInWithEmailAndPassword(user, pass)
|
||||
.then(() => {
|
||||
ToastAndroid.show('Successfully logged in', ToastAndroid.SHORT);
|
||||
})
|
||||
.catch(e => {
|
||||
ToastAndroid.show('Invalid username or password', ToastAndroid.SHORT);
|
||||
throw e;
|
||||
});
|
||||
}, []);
|
||||
|
||||
return logIn;
|
||||
};
|
||||
|
||||
export default useLogin;
|
17
src/hooks/useLogout.js
Normal file
17
src/hooks/useLogout.js
Normal file
@ -0,0 +1,17 @@
|
||||
import {useCallback} from 'react';
|
||||
import {ToastAndroid} from 'react-native';
|
||||
import auth from '@react-native-firebase/auth';
|
||||
|
||||
const useLogout = () => {
|
||||
const logOut = useCallback(() => {
|
||||
return auth()
|
||||
.signOut()
|
||||
.then(() => {
|
||||
ToastAndroid.show('Signed out', ToastAndroid.SHORT);
|
||||
});
|
||||
}, []);
|
||||
|
||||
return logOut;
|
||||
};
|
||||
|
||||
export default useLogout;
|
28
src/hooks/useSignup.js
Normal file
28
src/hooks/useSignup.js
Normal file
@ -0,0 +1,28 @@
|
||||
import {useCallback} from 'react';
|
||||
import {ToastAndroid} from 'react-native';
|
||||
import auth from '@react-native-firebase/auth';
|
||||
|
||||
const useSignup = () => {
|
||||
const signUp = useCallback((user, pass) => {
|
||||
return auth()
|
||||
.createUserWithEmailAndPassword(user, pass)
|
||||
.then(() => {
|
||||
ToastAndroid.show('Successfully registered!', ToastAndroid.SHORT);
|
||||
})
|
||||
.catch(e => {
|
||||
if (e.code == 'auth/email-already-in-use') {
|
||||
ToastAndroid.show('Email already in use', ToastAndroid.SHORT);
|
||||
} else if (e.code == 'auth/invalid-email') {
|
||||
ToastAndroid.show('Invalid email address', ToastAndroid.SHORT);
|
||||
} else {
|
||||
ToastAndroid.show('Failed to sign up', ToastAndroid.SHORT);
|
||||
}
|
||||
|
||||
throw e;
|
||||
});
|
||||
}, []);
|
||||
|
||||
return signUp;
|
||||
};
|
||||
|
||||
export default useSignup;
|
10
src/screens/Buckets.js
Normal file
10
src/screens/Buckets.js
Normal file
@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
import {StyleSheet, View, Text, ScrollView} from 'react-native';
|
||||
|
||||
const Buckets = () => {
|
||||
return (
|
||||
<Text>Signed in!!!</Text>
|
||||
)
|
||||
}
|
||||
|
||||
export default Buckets;
|
47
src/screens/Settings.js
Normal file
47
src/screens/Settings.js
Normal file
@ -0,0 +1,47 @@
|
||||
import React, {useCallback} from 'react';
|
||||
import {StyleSheet, View, Text, Button, TextInput} from 'react-native';
|
||||
import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
|
||||
import useLogout from '../hooks/useLogout';
|
||||
import {useNavigation} from '@react-navigation/native';
|
||||
|
||||
const Settings = () => {
|
||||
const logOut = useLogout();
|
||||
const navigation = useNavigation();
|
||||
|
||||
const onLogout = useCallback(() => {
|
||||
logOut().then(() => {
|
||||
navigation.reset({index: 0, routes: [{name: 'SignIn'}]});
|
||||
});
|
||||
}, [logOut]);
|
||||
|
||||
return (
|
||||
<KeyboardAwareScrollView style={styles.root}>
|
||||
<View style={styles.button}>
|
||||
<Button onPress={onLogout} title="Sign out" />
|
||||
</View>
|
||||
</KeyboardAwareScrollView>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
root: {
|
||||
flex: 1,
|
||||
backgroundColor: '#FEFEFE',
|
||||
padding: 10,
|
||||
},
|
||||
input: {
|
||||
height: 40,
|
||||
margin: 12,
|
||||
borderWidth: 1,
|
||||
padding: 10,
|
||||
borderRadius: 3,
|
||||
backgroundColor: '#DDDDDD',
|
||||
color: '#000000',
|
||||
},
|
||||
button: {
|
||||
margin: 12,
|
||||
marginBottom: 32,
|
||||
},
|
||||
});
|
||||
|
||||
export default Settings;
|
@ -1,19 +1,116 @@
|
||||
import React from 'react';
|
||||
import {View, Text, StyleSheet} from 'react-native';
|
||||
import React, {useState, useCallback} from 'react';
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
TextInput,
|
||||
Button,
|
||||
Pressable,
|
||||
ToastAndroid,
|
||||
StyleSheet,
|
||||
} from 'react-native';
|
||||
import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
|
||||
import {useNavigation} from '@react-navigation/native';
|
||||
import useLogin from '../hooks/useLogin';
|
||||
|
||||
const SignIn = () => {
|
||||
const navigation = useNavigation();
|
||||
const [email, setEmail] = useState('');
|
||||
const [pass, setPass] = useState('');
|
||||
const logIn = useLogin();
|
||||
|
||||
const onSubmit = useCallback(() => {
|
||||
if (!email || !pass) {
|
||||
ToastAndroid.show(
|
||||
'Error! You need to provide both an email and a password',
|
||||
ToastAndroid.SHORT,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
logIn(email, pass)
|
||||
.then(() => {
|
||||
console.log('asdasd');
|
||||
navigation.reset({index: 0, routes: [{name: 'Buckets'}]});
|
||||
})
|
||||
.catch(() => {});
|
||||
}, [email, pass, logIn, navigation]);
|
||||
|
||||
const onSignup = useCallback(() => {
|
||||
navigation.navigate('SignUp');
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<View style={styles.root}>
|
||||
<Text>Hello!</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
<KeyboardAwareScrollView style={styles.root}>
|
||||
<Text style={styles.title}>BrowseS3</Text>
|
||||
<Text style={styles.subtitle}>Made by: Fándly Gergő-Zoltán</Text>
|
||||
<Text style={styles.welcome}>Welcome! Please sign in to continue!</Text>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
placeholder="Email"
|
||||
value={email}
|
||||
onChangeText={setEmail}
|
||||
autoComplete="email"
|
||||
/>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
placeholder="Password"
|
||||
value={pass}
|
||||
onChangeText={setPass}
|
||||
autoComplete="password"
|
||||
secureTextEntry
|
||||
/>
|
||||
<View style={styles.button}>
|
||||
<Button onPress={onSubmit} title="Sign in" />
|
||||
</View>
|
||||
<Pressable onPress={onSignup}>
|
||||
<Text style={styles.signUp}>No account? Sign up here!</Text>
|
||||
</Pressable>
|
||||
</KeyboardAwareScrollView>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
root: {
|
||||
flex: 1,
|
||||
backgroundColor: '#FEFEFE'
|
||||
}
|
||||
})
|
||||
backgroundColor: '#FEFEFE',
|
||||
padding: 10,
|
||||
},
|
||||
title: {
|
||||
fontSize: 32,
|
||||
textAlign: 'center',
|
||||
marginTop: 32,
|
||||
color: '#000000',
|
||||
},
|
||||
subtitle: {
|
||||
color: '#000000',
|
||||
marginBottom: 132,
|
||||
textAlign: 'right',
|
||||
},
|
||||
welcome: {
|
||||
fontSize: 20,
|
||||
color: '#000000',
|
||||
marginBottom: 32,
|
||||
textAlign: 'center',
|
||||
},
|
||||
input: {
|
||||
height: 40,
|
||||
margin: 12,
|
||||
borderWidth: 1,
|
||||
padding: 10,
|
||||
borderRadius: 3,
|
||||
backgroundColor: '#DDDDDD',
|
||||
color: '#000000',
|
||||
},
|
||||
button: {
|
||||
margin: 12,
|
||||
marginBottom: 32,
|
||||
},
|
||||
signUp: {
|
||||
color: '#CCCCCC',
|
||||
fontSize: 12,
|
||||
textAlign: 'center',
|
||||
textDecorationLine: 'underline',
|
||||
},
|
||||
});
|
||||
|
||||
export default SignIn;
|
||||
export default SignIn;
|
||||
|
82
src/screens/SignUp.js
Normal file
82
src/screens/SignUp.js
Normal file
@ -0,0 +1,82 @@
|
||||
import React, {useState, useCallback} from 'react';
|
||||
import {StyleSheet, View, Text, TextInput, Button} from 'react-native';
|
||||
import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
|
||||
import useSignup from '../hooks/useSignup';
|
||||
import {useNavigation} from '@react-navigation/native';
|
||||
|
||||
const SignUp = () => {
|
||||
const [email, setEmail] = useState('');
|
||||
const [pass, setPass] = useState('');
|
||||
const signUp = useSignup();
|
||||
const navigation = useNavigation();
|
||||
|
||||
const onSubmit = useCallback(() => {
|
||||
if (!email || !pass) {
|
||||
ToastAndroid.show(
|
||||
'Error! You need to provide both an email and a password',
|
||||
ToastAndroid.SHORT,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
signUp(email, pass)
|
||||
.then(() => {
|
||||
console.log('asdasd');
|
||||
navigation.reset({index: 0, routes: [{name: 'Buckets'}]});
|
||||
})
|
||||
.catch(() => {});
|
||||
}, [email, pass, signUp, navigation]);
|
||||
|
||||
return (
|
||||
<KeyboardAwareScrollView style={styles.root}>
|
||||
<Text style={styles.help}>Let's create a new user for you!</Text>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
placeholder="Email"
|
||||
value={email}
|
||||
onChangeText={setEmail}
|
||||
autoComplete="email"
|
||||
/>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
placeholder="Password"
|
||||
value={pass}
|
||||
onChangeText={setPass}
|
||||
autoComplete="password-new"
|
||||
secureTextEntry
|
||||
/>
|
||||
<View style={styles.button}>
|
||||
<Button onPress={onSubmit} title="Sign up" />
|
||||
</View>
|
||||
</KeyboardAwareScrollView>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
root: {
|
||||
flex: 1,
|
||||
backgroundColor: '#FEFEFE',
|
||||
padding: 10,
|
||||
},
|
||||
help: {
|
||||
color: '#000000',
|
||||
fontSize: 18,
|
||||
textAlign: 'center',
|
||||
marginBottom: 32,
|
||||
},
|
||||
input: {
|
||||
height: 40,
|
||||
margin: 12,
|
||||
borderWidth: 1,
|
||||
padding: 10,
|
||||
borderRadius: 3,
|
||||
backgroundColor: '#DDDDDD',
|
||||
color: '#000000',
|
||||
},
|
||||
button: {
|
||||
margin: 12,
|
||||
marginBottom: 32,
|
||||
},
|
||||
});
|
||||
|
||||
export default SignUp;
|
Reference in New Issue
Block a user