diff options
author | Justin Shillingford <jgs272@cornell.edu> | 2020-06-29 16:13:29 -0400 |
---|---|---|
committer | Justin Shillingford <jgs272@cornell.edu> | 2020-06-29 16:13:29 -0400 |
commit | e8587757ced208708311d80838c9b24777f8edbb (patch) | |
tree | 4e7969ecd377767bcb4c03cf3d1536496ccdb6b0 | |
parent | 6ae1d1bedffae01379dbd71a2b5cbe4aae28d065 (diff) |
Created LoginInput Component
-rw-r--r-- | src/components/common/LoginInput.tsx | 58 | ||||
-rw-r--r-- | src/routes/Routes.tsx | 6 | ||||
-rw-r--r-- | src/screens/Login.tsx | 205 |
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; |