diff options
-rw-r--r-- | ios/Podfile.lock | 10 | ||||
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | src/routes/Routes.tsx | 2 | ||||
-rw-r--r-- | src/screens/Login.tsx | 225 | ||||
-rw-r--r-- | yarn.lock | 35 |
5 files changed, 246 insertions, 27 deletions
diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 693e204c..fcff1410 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,5 +1,7 @@ PODS: - boost-for-react-native (1.63.0) + - BVLinearGradient (2.5.6): + - React - CocoaAsyncSocket (7.6.4) - CocoaLibEvent (1.0.0) - DoubleConversion (1.1.6) @@ -233,7 +235,7 @@ PODS: - React-cxxreact (= 0.62.2) - React-jsi (= 0.62.2) - React-jsinspector (0.62.2) - - react-native-safe-area-context (3.0.6): + - react-native-safe-area-context (3.0.7): - React - React-RCTActionSheet (0.62.2): - React-Core/RCTActionSheetHeaders (= 0.62.2) @@ -307,6 +309,7 @@ PODS: - Yoga (~> 1.14) DEPENDENCIES: + - BVLinearGradient (from `../node_modules/react-native-linear-gradient`) - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) - FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`) @@ -376,6 +379,8 @@ SPEC REPOS: - YogaKit EXTERNAL SOURCES: + BVLinearGradient: + :path: "../node_modules/react-native-linear-gradient" DoubleConversion: :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" FBLazyVector: @@ -439,6 +444,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c + BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872 CocoaAsyncSocket: 694058e7c0ed05a9e217d1b3c7ded962f4180845 CocoaLibEvent: 2fab71b8bd46dd33ddb959f7928ec5909f838e3f DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 @@ -463,7 +469,7 @@ SPEC CHECKSUMS: React-jsi: b6dc94a6a12ff98e8877287a0b7620d365201161 React-jsiexecutor: 1540d1c01bb493ae3124ed83351b1b6a155db7da React-jsinspector: 512e560d0e985d0e8c479a54a4e5c147a9c83493 - react-native-safe-area-context: e22a8ca00f758273d2408953965cb8db67da7925 + react-native-safe-area-context: ef6f16c66b0797ecae1bf86c103dfb3dc16fc33d React-RCTActionSheet: f41ea8a811aac770e0cc6e0ad6b270c644ea8b7c React-RCTAnimation: 49ab98b1c1ff4445148b72a3d61554138565bad0 React-RCTBlob: a332773f0ebc413a0ce85942a55b064471587a71 diff --git a/package.json b/package.json index d3ad6c4d..0c8f7bf1 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "react": "16.11.0", "react-native": "0.62.2", "react-native-gesture-handler": "^1.6.1", + "react-native-linear-gradient": "^2.5.6", "react-native-reanimated": "^1.9.0", "react-native-safe-area-context": "^3.0.6", "react-native-screens": "^2.9.0" diff --git a/src/routes/Routes.tsx b/src/routes/Routes.tsx index 9c2efada..0b08cbb1 100644 --- a/src/routes/Routes.tsx +++ b/src/routes/Routes.tsx @@ -15,7 +15,7 @@ interface RoutesProps {} const Routes: React.FC<RoutesProps> = ({}) => { return ( <RootStack.Navigator initialRouteName="Login"> - <RootStack.Screen name="Login" component={Login} /> + <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 0305b907..672fd035 100644 --- a/src/screens/Login.tsx +++ b/src/screens/Login.tsx @@ -1,9 +1,19 @@ -import React from 'react'; +import React, { useRef } from 'react'; import {RouteProp} from '@react-navigation/native'; import {StackNavigationProp} from '@react-navigation/stack'; -import {View, Text, Button} from 'react-native'; +import { + View, + Text, + Alert, + StatusBar, + Image, + TextInput, + TouchableOpacity, + StyleSheet +} from 'react-native'; import {RootStackParams} from '../routes'; +import LinearGradient from 'react-native-linear-gradient'; type LoginScreenRouteProp = RouteProp<RootStackParams, 'Login'>; type LoginScreenNavigationProp = StackNavigationProp<RootStackParams, 'Login'>; @@ -13,15 +23,212 @@ interface LoginProps { navigation: LoginScreenNavigationProp; } const Login = ({navigation}: LoginProps) => { + const passwordInput = useRef(); + const [data, setData] = React.useState({ + username: '', + password: '', + isValidUser: true, + isValidPassword: true, + }) + + /* + Updates the state of username. Also verifies the input of the Username field. + */ + const handleUsernameUpdate = (val:string) => { + var validLength:boolean = val.trim().length >= 6 + + if (validLength) { + setData({ + ...data, + username: val, + isValidUser: true + }) + } + else { + setData({ + ...data, + username: val, + 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 + + if (validLength) { + setData({ + ...data, + password: val, + isValidPassword: true + }) + } + else { + setData({ + ...data, + password: val, + 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') + } + } + return ( - <View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}> - <Text style={{fontSize: 18}}>Welcome to Tagg! Login page goes here.</Text> - <Button - title="Register" - onPress={() => navigation.navigate('Registration')} + <> + <StatusBar + barStyle='light-content' /> - </View> + <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> + </Text> + </LinearGradient> + </View> + </> + // <View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}> + // <Text style={{fontSize: 18}}>Welcome to Tagg! Login page goes here.</Text> + // <Button + // title="Register" + // onPress={() => navigation.navigate('Registration')} + // /> + // </View> ); }; -export default Login; +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: 'transparent', + }, + linearGradient: { + flex: 1, + alignItems: 'center', + }, + logo: { + top: 165, + width: 215, + height: 149, + }, + credentials: { + top: 190, + width: 248, + height: 40, + fontSize: 20, + color: '#FFFFFF', + borderColor: '#FFFDFD', + borderWidth: 2, + borderRadius: 20, + paddingLeft: 13, + marginVertical: 15, + }, + forgotPassword: { + top: 190, + left: -60, + }, + forgotPasswordText: { + fontSize: 15, + color: '#FFFFFF', + textDecorationLine: 'underline', + }, + start: { + top: 195, + width: 144, + height: 36, + justifyContent: 'center', + alignItems: 'center', + backgroundColor: '#FFFFFF', + borderRadius: 20, + marginTop: 15 + }, + startText: { + fontSize: 15, + color: '#78A0EF', + fontWeight: 'bold', + }, + getStarted: { + color: '#FFFFFF', + textDecorationLine: 'underline' + }, + newUser: { + top: 240, + color: '#F4DDFF', + }, + invalidCredentials: { + top: 180, + color: '#F4DDFF' + } +}); + +export default Login;
\ No newline at end of file @@ -1127,9 +1127,9 @@ integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== "@types/react-native@^0.62.0": - version "0.62.13" - resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.62.13.tgz#c688c5ae03e426f927f7e1fa1a59cd067f35d1c2" - integrity sha512-hs4/tSABhcJx+J8pZhVoXHrOQD89WFmbs8QiDLNSA9zNrD46pityAuBWuwk1aMjPk9I3vC5ewkJroVRHgRIfdg== + version "0.62.14" + resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.62.14.tgz#13ce7dab136bb124b6f394fe7510442557b16d29" + integrity sha512-ItBgiEQks2Mid6GsiLBx75grNH0glaKemTK9V7G+vSnvP+Zk3x1Wr+aTy4dJxRPPMg14DAJyYePLZwj2cigXbw== dependencies: "@types/react" "*" @@ -1141,9 +1141,9 @@ "@types/react" "*" "@types/react@*": - version "16.9.38" - resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.38.tgz#868405dace93a4095d3e054f4c4a1de7a1ac0680" - integrity sha512-pHAeZbjjNRa/hxyNuLrvbxhhnKyKNiLC6I5fRF2Zr/t/S6zS41MiyzH4+c+1I9vVfvuRt1VS2Lodjr4ZWnxrdA== + version "16.9.41" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.41.tgz#925137ee4d2ff406a0ecf29e8e9237390844002e" + integrity sha512-6cFei7F7L4wwuM+IND/Q2cV1koQUvJ8iSV+Gwn0c3kvABZ691g7sp3hfEQHOUBJtccl1gPi+EyNjMIl9nGA0ug== dependencies: "@types/prop-types" "*" csstype "^2.2.0" @@ -3691,9 +3691,9 @@ jest-mock@^24.9.0: "@jest/types" "^24.9.0" jest-pnp-resolver@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a" - integrity sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ== + version "1.2.2" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" + integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== jest-regex-util@^24.3.0, jest-regex-util@^24.9.0: version "24.9.0" @@ -5107,6 +5107,11 @@ react-native-iphone-x-helper@^1.2.1: resolved "https://registry.yarnpkg.com/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.2.1.tgz#645e2ffbbb49e80844bb4cbbe34a126fda1e6772" integrity sha512-/VbpIEp8tSNNHIvstuA3Swx610whci1Zpc9mqNkqn14DkMbw+ORviln2u0XyHG1kPvvwTNGZY6QpeFwxYaSdbQ== +react-native-linear-gradient@^2.5.6: + version "2.5.6" + resolved "https://registry.yarnpkg.com/react-native-linear-gradient/-/react-native-linear-gradient-2.5.6.tgz#96215cbc5ec7a01247a20890888aa75b834d44a0" + integrity sha512-HDwEaXcQIuXXCV70O+bK1rizFong3wj+5Q/jSyifKFLg0VWF95xh8XQgfzXwtq0NggL9vNjPKXa016KuFu+VFg== + react-native-reanimated@^1.9.0: version "1.9.0" resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-1.9.0.tgz#38676c99dd585504fdc7331efb45e5f48ec7339a" @@ -5115,9 +5120,9 @@ react-native-reanimated@^1.9.0: fbjs "^1.0.0" react-native-safe-area-context@^3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-3.0.6.tgz#ee180f53f9f40f8302923b9c09d821cf8ada01eb" - integrity sha512-/McWHgRG3CjXo/1ctlxH3mjW2psjf/QYAt9kWUTEtHu4b6z1y4hfUIGuYEJ02asaS1ixPsYrkqVqwzTv4olUMQ== + version "3.0.7" + resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-3.0.7.tgz#0f53de7a30d626d82936000f3f6db374ecc4b800" + integrity sha512-dqhRTlIFe5+P1yxitj0C9XVUxLqOmjomeqzUSSY8sNOWVjtIhEY/fl4ZKYpAVnktd8dt3zl13XmJTmRmy3d0uA== react-native-screens@^2.9.0: version "2.9.0" @@ -6349,9 +6354,9 @@ whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: iconv-lite "0.4.24" whatwg-fetch@>=0.10.0, whatwg-fetch@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" - integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== + version "3.1.0" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.1.0.tgz#49d630cdfa308dba7f2819d49d09364f540dbcc6" + integrity sha512-pgmbsVWKpH9GxLXZmtdowDIqtb/rvPyjjQv3z9wLcmgWKFHilKnZD3ldgrOlwJoPGOUluQsRPWd52yVkPfmI1A== whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0: version "2.3.0" |