aboutsummaryrefslogtreecommitdiff
path: root/src/screens/Login.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/screens/Login.tsx')
-rw-r--r--src/screens/Login.tsx317
1 files changed, 0 insertions, 317 deletions
diff --git a/src/screens/Login.tsx b/src/screens/Login.tsx
deleted file mode 100644
index 1ddf6e0a..00000000
--- a/src/screens/Login.tsx
+++ /dev/null
@@ -1,317 +0,0 @@
-import React, {useRef} from 'react';
-import {RouteProp} from '@react-navigation/native';
-import {StackNavigationProp} from '@react-navigation/stack';
-import {
- View,
- Text,
- Alert,
- StatusBar,
- Image,
- TouchableOpacity,
- StyleSheet,
- KeyboardAvoidingView,
- Platform,
-} from 'react-native';
-
-import {RootStackParamList} from '../routes';
-import {Background, TaggInput, SubmitButton} from '../components';
-import {usernameRegex, LOGIN_ENDPOINT} from '../constants';
-
-type LoginScreenRouteProp = RouteProp<RootStackParamList, 'Login'>;
-type LoginScreenNavigationProp = StackNavigationProp<
- RootStackParamList,
- 'Login'
->;
-interface LoginProps {
- route: LoginScreenRouteProp;
- navigation: LoginScreenNavigationProp;
-}
-/**
- * Login screen.
- * @param navigation react-navigation navigation object.
- */
-const Login: React.FC<LoginProps> = ({navigation}: LoginProps) => {
- // ref for focusing on input fields
- const inputRef = useRef();
- // login form state
- const [form, setForm] = React.useState({
- username: '',
- password: '',
- isValidUser: false,
- isValidPassword: false,
- attemptedSubmit: false,
- });
-
- /**
- * Updates the state of username. Also verifies the input of the username field by ensuring proper length and characters.
- */
- const handleUsernameUpdate = (val: string) => {
- let validLength: boolean = val.length >= 6;
- let validChars: boolean = usernameRegex.test(val);
-
- if (validLength && validChars) {
- setForm({
- ...form,
- username: val,
- isValidUser: true,
- });
- } else {
- setForm({
- ...form,
- username: val,
- isValidUser: false,
- });
- }
- };
-
- /**
- * Updates the state of password. Also verifies the input of the password field by ensuring proper length.
- */
- const handlePasswordUpdate = (val: string) => {
- let validLength: boolean = val.trim().length >= 8;
-
- if (validLength) {
- setForm({
- ...form,
- password: val,
- isValidPassword: true,
- });
- } else {
- setForm({
- ...form,
- password: val,
- isValidPassword: false,
- });
- }
- };
-
- /*
- * Handles tap on username keyboard's "Next" button by focusing on password field.
- */
- const handleUsernameSubmit = () => {
- const passwordField: any = inputRef.current;
- if (passwordField) {
- passwordField.focus();
- }
- };
-
- /**
- * Handler for the Let's Start button or the Go button on the keyboard.
- Makes a POST request to the Django login API and presents Alerts based on the status codes that the backend returns.
- */
- const handleLogin = async () => {
- if (!form.attemptedSubmit) {
- setForm({
- ...form,
- attemptedSubmit: true,
- });
- }
- try {
- if (form.isValidUser && form.isValidPassword) {
- let response = await fetch(LOGIN_ENDPOINT, {
- method: 'POST',
- body: JSON.stringify({
- username: form.username,
- password: form.password,
- }),
- });
-
- let statusCode = response.status;
- if (statusCode === 200) {
- Alert.alert('Successfully logged in! 🥳', `Welcome ${form.username}`);
- } else if (statusCode === 401) {
- Alert.alert(
- 'Login failed 😔',
- 'Try re-entering your login information.',
- );
- } else {
- Alert.alert(
- 'Something went wrong! 😭',
- "Would you believe me if I told you that I don't know what happened?",
- );
- }
- } else {
- setForm({...form, attemptedSubmit: false});
- setTimeout(() => setForm({...form, attemptedSubmit: true}));
- }
- } catch (error) {
- Alert.alert(
- 'Looks like our servers are down. 😓',
- "Try again in a couple minutes. We're sorry for the inconvenience.",
- );
- return {
- name: 'Login error',
- description: error,
- };
- }
- };
-
- /*
- * Handles tap on "Get Started" text by resetting fields & navigating to the registration page.
- */
- const goToRegistration = () => {
- navigation.navigate('Registration');
- setForm({...form, attemptedSubmit: false});
- };
-
- /**
- * Login screen forgot password button.
- */
- const ForgotPassword = () => (
- <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>
- );
-
- /**
- * Login screen login button.
- */
- const LoginButton = () => (
- <SubmitButton
- text="Let's Start!"
- color="#fff"
- style={styles.button}
- accessibilityLabel="Let's Start!"
- accessibilityHint="Select this after entering your tagg username and password"
- onPress={handleLogin}
- />
- );
-
- /**
- * Login screen registration prompt.
- */
- const RegistrationPrompt = () => (
- <View style={styles.newUserContainer}>
- <Text
- accessible={true}
- accessibilityLabel="New to tagg?"
- style={styles.newUser}>
- New to tagg?{' '}
- </Text>
- <TouchableOpacity
- accessibilityLabel="Get started."
- accessibilityHint="Select this if you do not have a tagg account">
- <Text
- accessible={true}
- accessibilityLabel="Get started"
- style={styles.getStarted}
- onPress={goToRegistration}>
- Get started!
- </Text>
- </TouchableOpacity>
- </View>
- );
-
- return (
- <Background centered style={styles.container}>
- <StatusBar barStyle="light-content" />
- <KeyboardAvoidingView
- behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
- style={styles.keyboardAvoidingView}>
- <Image
- source={require('../assets/images/logo.png')}
- style={styles.logo}
- />
- <TaggInput
- accessibilityHint="Enter your tagg username here"
- accessibilityLabel="Username text entry box"
- placeholder="Username"
- autoCompleteType="username"
- textContentType="username"
- returnKeyType="next"
- autoCapitalize="none"
- onChangeText={handleUsernameUpdate}
- onSubmitEditing={handleUsernameSubmit}
- blurOnSubmit={false}
- valid={form.isValidUser}
- invalidWarning="Username must be at least 6 characters and can only contain letters, numbers, periods, and underscores."
- attemptedSubmit={form.attemptedSubmit}
- />
-
- <TaggInput
- accessibilityHint="Enter your tagg password here"
- accessibilityLabel="Password text entry box"
- placeholder="Password"
- autoCompleteType="password"
- textContentType="password"
- returnKeyType="go"
- autoCapitalize="none"
- secureTextEntry
- onChangeText={handlePasswordUpdate}
- onSubmitEditing={handleLogin}
- valid={form.isValidPassword}
- invalidWarning="Password must be at least 8 characters long."
- attemptedSubmit={form.attemptedSubmit}
- ref={inputRef}
- />
- <ForgotPassword />
- <LoginButton />
- </KeyboardAvoidingView>
- <RegistrationPrompt />
- </Background>
- );
-};
-
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'center',
- },
- keyboardAvoidingView: {
- alignItems: 'center',
- },
- logo: {
- width: 215,
- height: 149,
- marginBottom: '10%',
- },
- forgotPassword: {
- marginTop: 10,
- marginBottom: 15,
- },
- forgotPasswordText: {
- fontSize: 14,
- color: '#fff',
- textDecorationLine: 'underline',
- },
- start: {
- width: 144,
- height: 36,
- justifyContent: 'center',
- alignItems: 'center',
- backgroundColor: '#fff',
- borderRadius: 18,
- marginBottom: '15%',
- },
- startDisabled: {
- backgroundColor: '#ddd',
- },
- startText: {
- fontSize: 16,
- color: '#78a0ef',
- fontWeight: 'bold',
- },
- newUserContainer: {
- flexDirection: 'row',
- color: '#fff',
- },
- newUser: {
- fontSize: 14,
- color: '#f4ddff',
- },
- getStarted: {
- fontSize: 14,
- color: '#fff',
- textDecorationLine: 'underline',
- },
- button: {
- marginVertical: '10%'
- }
-});
-
-export default Login;