diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 78de2557497a01a043cb464aff90edf89a953785..591428e16423cfd5eea6981d8c22dd7293fa8c37 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -48,6 +48,8 @@ dependencies {
     implementation(libs.androidx.lifecycle.viewmodel.ktx)
     implementation(libs.androidx.navigation.fragment.ktx)
     implementation(libs.androidx.navigation.ui.ktx)
+    implementation("com.squareup.retrofit2:retrofit:2.9.0")
+    implementation("com.squareup.retrofit2:converter-gson:2.9.0")
     testImplementation(libs.junit)
     androidTestImplementation(libs.androidx.junit)
     androidTestImplementation(libs.androidx.espresso.core)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 052318c3097994f2fb30c25f346ff1cc2191dd88..3c98a8ba53033802c3db9594a1fabe427c682126 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,6 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools">
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
 
     <application
         android:allowBackup="true"
diff --git a/app/src/main/java/com/example/myapplication/LoginActivity.kt b/app/src/main/java/com/example/myapplication/LoginActivity.kt
index ba57925739990dccf234953d456cb97801766a05..9776f0c5ff177f86c5630fa15c62aa1209c9d74e 100644
--- a/app/src/main/java/com/example/myapplication/LoginActivity.kt
+++ b/app/src/main/java/com/example/myapplication/LoginActivity.kt
@@ -1,6 +1,7 @@
 package com.example.myapplication
 
 import android.os.Bundle
+import android.util.Log
 import android.widget.Button
 import com.google.android.material.bottomnavigation.BottomNavigationView
 import androidx.appcompat.app.AppCompatActivity
@@ -10,10 +11,15 @@ import androidx.navigation.ui.setupActionBarWithNavController
 import androidx.navigation.ui.setupWithNavController
 import com.example.myapplication.databinding.ActivityLoginBinding
 import com.example.myapplication.databinding.ActivityMainBinding
+import com.example.myapplication.repository.AuthRepository
+import com.example.myapplication.ui.login.UserViewModel
+import com.example.myapplication.util.LoginListener
 
-class LoginActivity : AppCompatActivity() {
+class LoginActivity : AppCompatActivity() , LoginListener {
 
     private lateinit var binding: ActivityLoginBinding
+    private var userViewModel : UserViewModel = UserViewModel()
+    private var authRepository : AuthRepository = AuthRepository(this)
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -30,9 +36,20 @@ class LoginActivity : AppCompatActivity() {
         val loginButton : Button = binding.loginButton
 
         loginButton.setOnClickListener {
-            finish()
+            authRepository.loginRequest(binding.emailInput.text.toString(), binding.passwordInput.text.toString())
+            Log.d("Development", "Activity: Login request sent")
         }
     }
 
+    override fun onLoginSuccess() {
+        userViewModel.setUser(binding.emailInput.text.toString(), binding.passwordInput.text.toString())
+        Log.d("Development", "Activity: Login success")
+        finish()
+    }
+
+    override fun onLoginFailure() {
+        Log.d("Development", "Activity: Login failed")
+    }
+
 
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/example/myapplication/MainActivity.kt b/app/src/main/java/com/example/myapplication/MainActivity.kt
index d33287594b50f36f6aafb938ed4d896c2b0714c2..4d6ef5da340dda102514f278d9206df3c9dda050 100644
--- a/app/src/main/java/com/example/myapplication/MainActivity.kt
+++ b/app/src/main/java/com/example/myapplication/MainActivity.kt
@@ -1,7 +1,12 @@
 package com.example.myapplication
 
+import android.content.Context
 import android.content.Intent
+import android.net.ConnectivityManager
+import android.net.NetworkCapabilities
+import android.net.NetworkInfo
 import android.os.Bundle
+import android.util.Log
 import com.google.android.material.bottomnavigation.BottomNavigationView
 import androidx.appcompat.app.AppCompatActivity
 import androidx.navigation.findNavController
@@ -33,12 +38,23 @@ class MainActivity : AppCompatActivity() {
         setupActionBarWithNavController(navController, appBarConfiguration)
         navView.setupWithNavController(navController)
 
+        val isOnline : String = if (isOnline()) "Online" else "Offline"
+        Log.i("Development", "Online Connectivity Status: $isOnline")
 
-        val loginIntent : Intent = Intent(this, LoginActivity::class.java)
+
+        val loginIntent = Intent(this, LoginActivity::class.java)
         startActivity(loginIntent)
     }
 
     override fun onStart() {
         super.onStart()
     }
+
+    private fun isOnline(): Boolean {
+        val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
+        val network = connectivityManager.activeNetwork ?: return false
+        val networkCapabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
+        return networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
+                networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
+    }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/example/myapplication/backendconnect/BackendService.kt b/app/src/main/java/com/example/myapplication/backendconnect/BackendService.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f759e9c8b97fa53b1e6b02ceb0937b0daa5d2d1f
--- /dev/null
+++ b/app/src/main/java/com/example/myapplication/backendconnect/BackendService.kt
@@ -0,0 +1,19 @@
+package com.example.myapplication.backendconnect
+
+import com.example.myapplication.model.auth.Token
+import com.example.myapplication.model.auth.UserCred
+import retrofit2.Call
+import retrofit2.http.Body
+import retrofit2.http.POST
+import java.net.PasswordAuthentication
+
+interface BackendService {
+    @POST("auth/login")
+    fun login(@Body userCred: UserCred): Call<Token>
+
+    @POST("auth/token")
+    fun tokenCheck(@Body token: Token): Call<Token>
+
+//    @POST("bill/upload")
+//    fun uploadBill(@Body bill: Bill): Call<BillResponse>
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/myapplication/backendconnect/Client.kt b/app/src/main/java/com/example/myapplication/backendconnect/Client.kt
new file mode 100644
index 0000000000000000000000000000000000000000..704dcfa3b7c20d005f94be3051ce1f438bf2be09
--- /dev/null
+++ b/app/src/main/java/com/example/myapplication/backendconnect/Client.kt
@@ -0,0 +1,16 @@
+package com.example.myapplication.backendconnect
+
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+object Client {
+    private const val BASE_URL = "https://pbd-backend-2024.vercel.app/api/"
+
+    val connect : BackendService by lazy {
+        val retrofit = Retrofit.Builder()
+            .baseUrl(BASE_URL)
+            .addConverterFactory(GsonConverterFactory.create())
+            .build()
+
+        retrofit.create(BackendService::class.java)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/myapplication/model/auth/Token.kt b/app/src/main/java/com/example/myapplication/model/auth/Token.kt
new file mode 100644
index 0000000000000000000000000000000000000000..7fcdd2e724bac0b2f1f76235fbb9b5483de520d5
--- /dev/null
+++ b/app/src/main/java/com/example/myapplication/model/auth/Token.kt
@@ -0,0 +1,8 @@
+package com.example.myapplication.model.auth
+
+import com.google.gson.annotations.SerializedName
+
+data class Token (
+    @SerializedName("token")
+    val token: String
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/example/myapplication/model/auth/UserCred.kt b/app/src/main/java/com/example/myapplication/model/auth/UserCred.kt
new file mode 100644
index 0000000000000000000000000000000000000000..c46eb7c1d95418954d00efb8464c9b49f265f63d
--- /dev/null
+++ b/app/src/main/java/com/example/myapplication/model/auth/UserCred.kt
@@ -0,0 +1,10 @@
+package com.example.myapplication.model.auth
+
+import com.google.gson.annotations.SerializedName
+
+data class UserCred (
+    @SerializedName("email")
+    val email: String,
+    @SerializedName("password")
+    val password: String
+    )
\ No newline at end of file
diff --git a/app/src/main/java/com/example/myapplication/repository/AuthRepository.kt b/app/src/main/java/com/example/myapplication/repository/AuthRepository.kt
new file mode 100644
index 0000000000000000000000000000000000000000..12787498a5ab0fc15a61414f1cc26d99c4b0201d
--- /dev/null
+++ b/app/src/main/java/com/example/myapplication/repository/AuthRepository.kt
@@ -0,0 +1,40 @@
+package com.example.myapplication.repository
+
+import android.util.Log
+import com.example.myapplication.backendconnect.Client
+import com.example.myapplication.model.auth.Token
+import com.example.myapplication.model.auth.UserCred
+import com.example.myapplication.util.LoginListener
+import retrofit2.Call
+import retrofit2.Callback
+import retrofit2.Response
+
+class AuthRepository (private val loginListener: LoginListener) {
+
+    fun loginRequest(email: String, password: String){
+        Log.d("Development", "Login request to backend service")
+        Client.connect.login(UserCred(email, password)).enqueue(
+            object : Callback<Token> {
+                override fun onResponse(call: Call<Token>, response: Response<Token>) {
+                    Log.d("Development", "Response: ${response.body()}")
+                    if (response.isSuccessful) {
+                        val token = response.body()
+                        Log.d("Development", "Successful Login\nToken: ${token?.token}")
+                        loginListener.onLoginSuccess()
+                        // TODO: Save token to shared preferences
+                    } else {
+                        Log.d("Development", "LOGIN FAILED, http code : ${response.code()}")
+                        // Handle error
+                        loginListener.onLoginFailure()
+                    }
+                }
+
+                override fun onFailure(call: Call<Token>, t: Throwable) {
+                    Log.d("Development", "LOGIN FAILED, error on delivery : ${t.message}")
+                    // Handle error
+                    loginListener.onLoginFailure()
+                }
+            }
+        )
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/myapplication/ui/login/UserViewModel.kt b/app/src/main/java/com/example/myapplication/ui/login/UserViewModel.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f1d90ec8a86e10665cf6fcaafc4dfafa1e5764e2
--- /dev/null
+++ b/app/src/main/java/com/example/myapplication/ui/login/UserViewModel.kt
@@ -0,0 +1,21 @@
+package com.example.myapplication.ui.login
+
+import android.app.Application
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.ViewModel
+import com.example.myapplication.repository.AuthRepository
+import com.example.myapplication.util.LoginListener
+
+class UserViewModel() : ViewModel(){
+    var email: String = ""
+    var password: String = ""
+    var loginSuccesful: Boolean = false
+
+
+    fun setUser(email: String, password: String){
+        this.email = email
+        this.password = password
+    }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/myapplication/util/LoginListener.kt b/app/src/main/java/com/example/myapplication/util/LoginListener.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f04384f5de4b54153dbab28d119dec1ae5df3e1a
--- /dev/null
+++ b/app/src/main/java/com/example/myapplication/util/LoginListener.kt
@@ -0,0 +1,6 @@
+package com.example.myapplication.util
+
+interface LoginListener {
+    fun onLoginSuccess()
+    fun onLoginFailure()
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/login_cursor.xml b/app/src/main/res/drawable/login_cursor.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b62e07e6eaafe40fdeb6f04a127e0fdc976d08c4
--- /dev/null
+++ b/app/src/main/res/drawable/login_cursor.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <size android:width="2dp" />
+    <solid android:color="?attr/colorOnSecondary" />
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/rounded_rectangle.xml b/app/src/main/res/drawable/rounded_rectangle.xml
index 1008bc013a1fe66b65d41d26babd13471dcf2cdf..11c13dc32f2debea7bd3511363272bba8f9863d7 100644
--- a/app/src/main/res/drawable/rounded_rectangle.xml
+++ b/app/src/main/res/drawable/rounded_rectangle.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <shape xmlns:android="http://schemas.android.com/apk/res/android">
-    <solid android:color="@color/theme_red" />
+    <solid android:color="?attr/colorSecondary" />
     <corners android:radius="10dp" />
 
 </shape>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml
index 95be77f44fa099d147ca630460eb83a6da39c6dc..e97cc7b369e479338e3adba1ad531dd8e8335685 100644
--- a/app/src/main/res/layout/activity_login.xml
+++ b/app/src/main/res/layout/activity_login.xml
@@ -21,6 +21,8 @@
             android:layout_height="wrap_content"
             android:autofillHints="emailAddress"
             android:inputType="textEmailAddress"
+            android:label="@string/email_hint"
+            android:textCursorDrawable="@drawable/login_cursor"
             android:hint="@string/email_hint"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintStart_toStartOf="parent"
@@ -33,6 +35,8 @@
             android:layout_width="0dp"
             android:layout_height="wrap_content"
             android:autofillHints="password"
+            android:label="@string/password_hint"
+            android:textCursorDrawable="@drawable/login_cursor"
             android:hint="@string/password_hint"
             android:inputType="textPassword"
             app:layout_constraintEnd_toEndOf="parent"