aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Shillingford <jgs272@cornell.edu>2020-06-29 16:13:29 -0400
committerJustin Shillingford <jgs272@cornell.edu>2020-06-29 16:13:29 -0400
commite8587757ced208708311d80838c9b24777f8edbb (patch)
tree4e7969ecd377767bcb4c03cf3d1536496ccdb6b0
parent6ae1d1bedffae01379dbd71a2b5cbe4aae28d065 (diff)
Created LoginInput Component
-rw-r--r--src/components/common/LoginInput.tsx58
-rw-r--r--src/routes/Routes.tsx6
-rw-r--r--src/screens/Login.tsx205
3 files changed, 169 insertions, 100 deletions
diff --git a/src/components/common/LoginInput.tsx b/src/components/common/LoginInput.tsx
new file mode 100644
index 00000000..ca33db92
--- /dev/null
+++ b/src/components/common/LoginInput.tsx
@@ -0,0 +1,58 @@
+import React from 'react';
+import {TextInput, StyleSheet} from 'react-native';
+import PropTypes from 'prop-types';
+
+const LoginInput = (props: LoginInputProps) => {
+ return (
+ <TextInput
+ accessibilityLabel={
+ props.isUsername ? 'Username text entry box' : 'Password text entry box'
+ }
+ accessibilityHint={
+ props.isUsername
+ ? 'Enter your tagg username here'
+ : 'Enter your tagg password here'
+ }
+ style={styles.credentials}
+ placeholder={props.isUsername ? 'Username' : 'Password'}
+ placeholderTextColor="#FFFFFF"
+ autoCompleteType={props.isUsername ? 'username' : 'password'}
+ textContentType={props.isUsername ? 'username' : 'password'}
+ returnKeyType={props.isUsername ? 'next' : 'go'}
+ keyboardType={props.isUsername ? 'ascii-capable' : 'default'}
+ onChangeText={(input) => props.onChangeText(input)}
+ defaultValue={props.type}
+ onSubmitEditing={props.onSubmitEditing}
+ blurOnSubmit={props.isUsername ? false : undefined}
+ // ref={props.isUsername ? undefined : useRef()}
+ secureTextEntry={props.isUsername ? false : true}
+ focus={props.isUsername ? undefined : props.focusPasswordInput}
+ />
+ );
+};
+
+const styles = StyleSheet.create({
+ credentials: {
+ top: 190,
+ width: 248,
+ height: 40,
+ fontSize: 20,
+ color: '#FFFFFF',
+ borderColor: '#FFFDFD',
+ borderWidth: 2,
+ borderRadius: 20,
+ paddingLeft: 13,
+ marginVertical: 15,
+ },
+});
+
+LoginInput.propTypes = {
+ type: PropTypes.string.isRequired,
+ isUsername: PropTypes.bool.isRequired,
+ onChangeText: PropTypes.func.isRequired,
+ onSubmitEditing: PropTypes.func,
+ ref: PropTypes.any,
+ focusPasswordInput: PropTypes.bool,
+};
+
+export default LoginInput;
diff --git a/src/routes/Routes.tsx b/src/routes/Routes.tsx
index 0b08cbb1..d96c1d80 100644
--- a/src/routes/Routes.tsx
+++ b/src/routes/Routes.tsx
@@ -15,7 +15,11 @@ interface RoutesProps {}
const Routes: React.FC<RoutesProps> = ({}) => {
return (
<RootStack.Navigator initialRouteName="Login">
- <RootStack.Screen name="Login" component={Login} options={ { headerShown: false} }/>
+ <RootStack.Screen
+ name="Login"
+ component={Login}
+ options={{headerShown: false}}
+ />
<RootStack.Screen name="Registration" component={Registration} />
</RootStack.Navigator>
);
diff --git a/src/screens/Login.tsx b/src/screens/Login.tsx
index 672fd035..2b4a10dc 100644
--- a/src/screens/Login.tsx
+++ b/src/screens/Login.tsx
@@ -1,20 +1,21 @@
-import React, { useRef } from 'react';
+import React from 'react';
import {RouteProp} from '@react-navigation/native';
import {StackNavigationProp} from '@react-navigation/stack';
import {
- View,
- Text,
- Alert,
- StatusBar,
- Image,
- TextInput,
- TouchableOpacity,
- StyleSheet
+ View,
+ Text,
+ Alert,
+ StatusBar,
+ Image,
+ TouchableOpacity,
+ StyleSheet,
} from 'react-native';
import {RootStackParams} from '../routes';
import LinearGradient from 'react-native-linear-gradient';
+import LoginInput from '../components/common/LoginInput';
+
type LoginScreenRouteProp = RouteProp<RootStackParams, 'Login'>;
type LoginScreenNavigationProp = StackNavigationProp<RootStackParams, 'Login'>;
@@ -23,137 +24,143 @@ interface LoginProps {
navigation: LoginScreenNavigationProp;
}
const Login = ({navigation}: LoginProps) => {
- const passwordInput = useRef();
+ // const passwordInput = useRef();
const [data, setData] = React.useState({
username: '',
password: '',
isValidUser: true,
isValidPassword: true,
- })
+ focusPasswordInput: false,
+ });
/*
Updates the state of username. Also verifies the input of the Username field.
*/
- const handleUsernameUpdate = (val:string) => {
- var validLength:boolean = val.trim().length >= 6
+ const handleUsernameUpdate = (val: string) => {
+ var validLength: boolean = val.trim().length >= 6;
if (validLength) {
setData({
...data,
username: val,
- isValidUser: true
- })
- }
- else {
+ isValidUser: true,
+ });
+ } else {
setData({
...data,
username: val,
- isValidUser: false
- })
+ isValidUser: false,
+ });
}
- }
+ };
/*
Updates the state of password. Also verifies the input of the Password field.
*/
- const handlePasswordUpdate = (val:string) => {
- var validLength:boolean = val.trim().length >= 8
+ const handlePasswordUpdate = (val: string) => {
+ var validLength: boolean = val.trim().length >= 8;
if (validLength) {
setData({
...data,
password: val,
- isValidPassword: true
- })
- }
- else {
+ isValidPassword: true,
+ });
+ } else {
setData({
...data,
password: val,
- isValidPassword: false
- })
- }
- }
+ isValidPassword: false,
+ });
+ }
+ };
/*
Handler for the Let's Start button or the Go button on the keyboard.
*/
const handleLogin = () => {
if (data.isValidUser && data.isValidPassword) {
- Alert.alert(`My favorite Girl Scout Cookies are taggalongs! What are yours ${data.username}?`)
- navigation.navigate('Registration')
+ Alert.alert(
+ `My favorite Girl Scout Cookies are taggalongs! What are yours ${data.username}?`,
+ );
+ navigation.navigate('Registration');
}
- }
-
+ };
+
+ const handleUsernameSubmit = () => {
+ setData({
+ ...data,
+ focusPasswordInput: true,
+ });
+ };
+
return (
<>
- <StatusBar
- barStyle='light-content'
- />
+ <StatusBar barStyle="light-content" />
<View style={styles.container}>
<LinearGradient
colors={['#8F00FF', '#6EE7E7']}
style={styles.linearGradient}
useAngle={true}
angle={154.72}
- angleCenter={{x:0.5,y:0.5}}>
- <Image
- source={require('../assets/images/logo.png')}
- style={styles.logo}
- />
- <TextInput
- accessibilityLabel="Username text entry box"
- accessibilityHint="Enter your tagg username here"
- style={styles.credentials}
- placeholder="Username"
- placeholderTextColor='#FFFFFF'
- autoCompleteType='username'
- textContentType='username'
- returnKeyType='next'
- keyboardType='ascii-capable'
- onChangeText={user => handleUsernameUpdate(user)}
- defaultValue={data.username}
- onSubmitEditing={() => {passwordInput.current.focus()}}
- blurOnSubmit={false}
- />
- { data.isValidUser ? null :
- <Text style={styles.invalidCredentials}>Username must be at least 6 characters long.</Text>
- }
- <TextInput
- accessibilityLabel="Password text entry box"
- accessibilityHint="Enter your tagg password here"
- style={styles.credentials}
- placeholder="Password"
- placeholderTextColor='#FFFFFF'
- autoCompleteType='password'
- textContentType='password'
- returnKeyType='go'
- onChangeText={pass => handlePasswordUpdate(pass)}
- defaultValue={data.password}
- onSubmitEditing={() => handleLogin()}
- ref={passwordInput}
- secureTextEntry={true}
- />
- { data.isValidPassword ? null :
- <Text style={styles.invalidCredentials}>Password must be at least 8 characters long.</Text>
- }
- <TouchableOpacity
- accessibilityLabel="Forgot password button"
- accessibilityHint="Select this if you forgot your tagg password"
- style={styles.forgotPassword}
- onPress={() => Alert.alert("tagg! You're it!")}>
- <Text style={styles.forgotPasswordText}>Forgot password</Text>
- </TouchableOpacity>
- <TouchableOpacity
- accessibilityLabel="Let's start button"
- accessibilityHint="Select this after entering your tagg username and password"
- style={styles.start}
- onPress={() => handleLogin()}>
- <Text style={styles.startText}>Let's Start!</Text>
- </TouchableOpacity>
- <Text accessible={true} accessibilityLabel="New to tagg?" style={styles.newUser}>
- New to tagg? <Text accessible={true} accessibilityLabel="Get started" accessibilityHint="Select this if you do not have a tagg account" style={styles.getStarted} onPress={() => Alert.alert("I get the tagg flip it and tumble it.")}>Get started!</Text>
+ angleCenter={{x: 0.5, y: 0.5}}>
+ <Image
+ source={require('../assets/images/logo.png')}
+ style={styles.logo}
+ />
+ <LoginInput
+ type={data.username}
+ isUsername={true}
+ onChangeText={(user) => handleUsernameUpdate(user)}
+ onSubmitEditing={() => handleUsernameSubmit()}
+ />
+ {data.isValidUser ? null : (
+ <Text style={styles.invalidCredentials}>
+ Username must be at least 6 characters long.
</Text>
+ )}
+ <LoginInput
+ type={data.password}
+ isUsername={false}
+ onChangeText={(user) => handlePasswordUpdate(user)}
+ focusPasswordInput={data.focusPasswordInput}
+ onSubmitEditing={() => handleLogin()}
+ />
+ {data.isValidPassword ? null : (
+ <Text style={styles.invalidCredentials}>
+ Password must be at least 8 characters long.
+ </Text>
+ )}
+ <TouchableOpacity
+ accessibilityLabel="Forgot password button"
+ accessibilityHint="Select this if you forgot your tagg password"
+ style={styles.forgotPassword}
+ onPress={() => Alert.alert("tagg! You're it!")}>
+ <Text style={styles.forgotPasswordText}>Forgot password</Text>
+ </TouchableOpacity>
+ <TouchableOpacity
+ accessibilityLabel="Let's start button"
+ accessibilityHint="Select this after entering your tagg username and password"
+ style={styles.start}
+ onPress={() => handleLogin()}>
+ <Text style={styles.startText}>Let's Start!</Text>
+ </TouchableOpacity>
+ <Text
+ accessible={true}
+ accessibilityLabel="New to tagg?"
+ style={styles.newUser}>
+ New to tagg?{' '}
+ <Text
+ accessible={true}
+ accessibilityLabel="Get started"
+ accessibilityHint="Select this if you do not have a tagg account"
+ style={styles.getStarted}
+ onPress={() =>
+ Alert.alert('I get the tagg flip it and tumble it.')
+ }>
+ Get started!
+ </Text>
+ </Text>
</LinearGradient>
</View>
</>
@@ -210,7 +217,7 @@ const styles = StyleSheet.create({
alignItems: 'center',
backgroundColor: '#FFFFFF',
borderRadius: 20,
- marginTop: 15
+ marginTop: 15,
},
startText: {
fontSize: 15,
@@ -219,7 +226,7 @@ const styles = StyleSheet.create({
},
getStarted: {
color: '#FFFFFF',
- textDecorationLine: 'underline'
+ textDecorationLine: 'underline',
},
newUser: {
top: 240,
@@ -227,8 +234,8 @@ const styles = StyleSheet.create({
},
invalidCredentials: {
top: 180,
- color: '#F4DDFF'
- }
+ color: '#F4DDFF',
+ },
});
-export default Login; \ No newline at end of file
+export default Login;