aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/assets/sign_in_logo.pngbin28865 -> 0 bytes
-rw-r--r--src/constants/index.ts5
-rw-r--r--src/screens/Login.tsx77
3 files changed, 54 insertions, 28 deletions
diff --git a/src/assets/sign_in_logo.png b/src/assets/sign_in_logo.png
deleted file mode 100644
index 27e43268..00000000
--- a/src/assets/sign_in_logo.png
+++ /dev/null
Binary files differ
diff --git a/src/constants/index.ts b/src/constants/index.ts
new file mode 100644
index 00000000..0667a187
--- /dev/null
+++ b/src/constants/index.ts
@@ -0,0 +1,5 @@
+// Backend API constants
+export const API_ENDPOINT: string = 'http://127.0.0.1:8000/api/';
+export const LOGIN_ENDPOINT: string = 'http://127.0.0.1:8000/api/login/';
+export const LOGOUT_ENDPOINT: string = 'http://127.0.0.1:8000/api/logout/';
+export const REGISTER_ENDPOINT: string = 'http://127.0.0.1:8000/api/register/';
diff --git a/src/screens/Login.tsx b/src/screens/Login.tsx
index 2a4ec060..5291b643 100644
--- a/src/screens/Login.tsx
+++ b/src/screens/Login.tsx
@@ -1,4 +1,4 @@
-import React, {useRef} from 'react';
+import React from 'react';
import {RouteProp} from '@react-navigation/native';
import {StackNavigationProp} from '@react-navigation/stack';
import {
@@ -18,6 +18,8 @@ import LinearGradient from 'react-native-linear-gradient';
import LoginInput from '../components/common/LoginInput';
+import * as Constants from '../constants';
+
type LoginScreenRouteProp = RouteProp<RootStackParams, 'Login'>;
type LoginScreenNavigationProp = StackNavigationProp<RootStackParams, 'Login'>;
@@ -27,23 +29,21 @@ interface LoginProps {
}
const Login = ({navigation}: LoginProps) => {
- const input_ref = useRef();
+ const input_ref = React.createRef();
const [data, setData] = React.useState({
username: '',
password: '',
- isValidUser: false,
- isValidPassword: false,
- attemptSubmit: false,
+ isValidUser: true,
+ isValidPassword: true,
});
/*
- Updates the state of username. Also verifies the input of the Username field by ensuring proper length and characters.
+ Updates the state of username. Also verifies the input of the Username field.
*/
const handleUsernameUpdate = (val: string) => {
- let validLength: boolean = val.length >= 6;
- let validChars: boolean = !/[^A-Za-z0-9_.]/g.test(val);
+ let validLength: boolean = val.trim().length >= 6;
- if (validLength && validChars) {
+ if (validLength) {
setData({
...data,
username: val,
@@ -59,10 +59,10 @@ const Login = ({navigation}: LoginProps) => {
};
/*
- Updates the state of password. Also verifies the input of the Password field by ensuring proper length.
+ Updates the state of password. Also verifies the input of the Password field.
*/
const handlePasswordUpdate = (val: string) => {
- let validLength: boolean = val.length >= 8;
+ let validLength: boolean = val.trim().length >= 8;
if (validLength) {
setData({
@@ -81,18 +81,43 @@ const Login = ({navigation}: LoginProps) => {
/*
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 = () => {
- if (!data.attemptSubmit) {
- setData({
- ...data,
- attemptSubmit: true,
- });
- }
- if (data.isValidUser && data.isValidPassword) {
+ const handleLogin = async () => {
+ try {
+ if (data.isValidUser && data.isValidPassword) {
+ let response = await fetch(Constants.LOGIN_ENDPOINT, {
+ method: 'POST',
+ body: JSON.stringify({
+ username: data.username,
+ password: data.password,
+ }),
+ });
+
+ let statusCode = response.status;
+ if (statusCode === 200) {
+ Alert.alert('Successfully logged in! 🥳', `Welcome ${data.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?",
+ );
+ }
+ }
+ } catch (error) {
Alert.alert(
- `My favorite Girl Scout Cookies are taggalongs! What are yours ${data.username}?`,
+ 'Looks like our servers are down. 😓',
+ "Try again in a couple minutes. We're sorry for the inconvenience.",
);
+ return {
+ name: 'Login error',
+ description: error,
+ };
}
};
@@ -128,13 +153,10 @@ const Login = ({navigation}: LoginProps) => {
<LoginInput
type={data.username}
isUsername={true}
- onChangeText={(user) => handleUsernameUpdate(user.trim())}
+ onChangeText={(user) => handleUsernameUpdate(user)}
onSubmitEditing={() => handleUsernameSubmit()}
isValid={data.isValidUser}
- validationWarning={
- 'Username must be at least 6 characters and can only contain letters, numbers, periods, and underscores.'
- }
- attempt_submit={data.attemptSubmit}
+ validationWarning={'Username must be at least 6 characters long.'}
/>
<LoginInput
type={data.password}
@@ -144,7 +166,6 @@ const Login = ({navigation}: LoginProps) => {
isValid={data.isValidPassword}
validationWarning={'Password must be at least 8 characters long.'}
input_ref={input_ref}
- attempt_submit={data.attemptSubmit}
/>
<TouchableOpacity
accessibilityLabel="Forgot password button"
@@ -196,7 +217,7 @@ const styles = StyleSheet.create({
height: 149,
},
forgotPassword: {
- top: 175,
+ top: 190,
left: -60,
},
forgotPasswordText: {
@@ -205,7 +226,7 @@ const styles = StyleSheet.create({
textDecorationLine: 'underline',
},
start: {
- top: 180,
+ top: 195,
width: 144,
height: 36,
justifyContent: 'center',