diff --git a/app/build.gradle.kts b/app/build.gradle.kts index e32d0592cc306a3c6312bcf3d308033c28061595..688cf12c38f7c4eea63c299bc60efc0499e43bfe 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -49,6 +49,8 @@ dependencies { implementation(libs.androidx.recyclerview) implementation(libs.androidx.room.runtime) implementation(libs.androidx.room.ktx) + implementation(libs.androidx.retrofit) + implementation(libs.androidx.retrofit.gson) implementation(libs.poi) implementation(libs.poi.ooxml) annotationProcessor(libs.androidx.room.compiler) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d8c0d23f8633871af96d8e8afc3c0af3fe200e29..40951b56bc8fa1f9e54b5e03f1e0163d42327b56 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,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" /> + <application android:name=".ABEApplication" android:allowBackup="true" @@ -13,9 +15,11 @@ android:supportsRtl="true" android:theme="@style/Theme.ABE" tools:targetApi="31"> - <activity - android:name=".MainActivity" + <activity android:name=".MainActivity" android:exported="true"> + </activity> + <activity + android:name=".ui.login.LoginActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> diff --git a/app/src/main/java/com/example/abe/connection/retrofit.kt b/app/src/main/java/com/example/abe/connection/retrofit.kt new file mode 100644 index 0000000000000000000000000000000000000000..03d15e5821fb4f7ae340dd0ab0f0441c296e8034 --- /dev/null +++ b/app/src/main/java/com/example/abe/connection/retrofit.kt @@ -0,0 +1,52 @@ +package com.example.abe.connection + +import com.example.abe.services.LoginService +import com.example.abe.types.LoginRequest +import com.example.abe.types.LoginResponse +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + +class CallBack<T> : Callback<T> { + override fun onResponse(call: Call<T>, response: Response<T>) { + if (response.isSuccessful) { + // Handle successful response + val data = response.body() + // Process the data here + if (data is LoginResponse) { + // Handle LoginResponse + println("Login successful $data") + } + } else { + // Handle error response + // Maybe use response.errorBody() to get error details + println("Login failed") + } + } + + override fun onFailure(call: Call<T>, t: Throwable) { + // Handle failure + println("Failed to send request") + } +} + +class Retrofit { + + private val url = "https://pbd-backend-2024.vercel.app/" + private val retrofit = Retrofit.Builder() + .baseUrl(url) + .addConverterFactory(GsonConverterFactory.create()) + .build() + + fun Login(email: String, password: String) { + val loginService = retrofit.create(LoginService::class.java) + + val call: Call<LoginResponse> = loginService.login( + LoginRequest(email, password) + ) + + call.enqueue(CallBack()) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/abe/data/network/Retrofit.kt b/app/src/main/java/com/example/abe/data/network/Retrofit.kt new file mode 100644 index 0000000000000000000000000000000000000000..8830bec0f1083ac71048effd3fe6d754bda7e286 --- /dev/null +++ b/app/src/main/java/com/example/abe/data/network/Retrofit.kt @@ -0,0 +1,64 @@ +package com.example.abe.data.network + +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + +interface LoginResultCallback { + fun onSuccess(loginResponse: LoginResponse) + fun onFailure(errorMessage: String) +} + +class CallBack<T> : Callback<T> { + override fun onResponse(call: Call<T>, response: Response<T>) { + if (response.isSuccessful) { + // Handle successful response + val data = response.body() + // Process the data here + if (data is LoginResponse) { + // Handle LoginResponse + println("Login successful $data") + } + } else { + // Handle error response + // Maybe use response.errorBody() to get error details + println("Login failed") + } + } + + override fun onFailure(call: Call<T>, t: Throwable) { + // Handle failure + println("Failed to send request") + } +} + +class Retrofit { + + private val retrofit = Retrofit.Builder() + .baseUrl("https://pbd-backend-2024.vercel.app/") + .addConverterFactory(GsonConverterFactory.create()) + .build() + + fun login(email: String, password: String, callback: LoginResultCallback) { + val loginService = retrofit.create(LoginService::class.java) + val call: Call<LoginResponse> = loginService.login(LoginRequest(email, password)) + + call.enqueue(object : Callback<LoginResponse> { + override fun onResponse(call: Call<LoginResponse>, response: Response<LoginResponse>) { + if (response.isSuccessful) { + response.body()?.let { + callback.onSuccess(it) + } + } else { + callback.onFailure("Login failed") + } + } + + override fun onFailure(call: Call<LoginResponse>, t: Throwable) { + callback.onFailure("Failed to send request") + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/abe/data/network/Services.kt b/app/src/main/java/com/example/abe/data/network/Services.kt new file mode 100644 index 0000000000000000000000000000000000000000..d1b74f4174464822d9d0bdd1fc7fec98d414cbbb --- /dev/null +++ b/app/src/main/java/com/example/abe/data/network/Services.kt @@ -0,0 +1,12 @@ +package com.example.abe.data.network + +import com.example.abe.data.network.LoginRequest +import com.example.abe.data.network.LoginResponse +import retrofit2.Call +import retrofit2.http.Body +import retrofit2.http.POST + +interface LoginService { + @POST("api/auth/login") + fun login(@Body user: LoginRequest) : Call<LoginResponse> +} \ No newline at end of file diff --git a/app/src/main/java/com/example/abe/data/network/Types.kt b/app/src/main/java/com/example/abe/data/network/Types.kt new file mode 100644 index 0000000000000000000000000000000000000000..a43f86a8b74eff310c05f8f4593f145236071d73 --- /dev/null +++ b/app/src/main/java/com/example/abe/data/network/Types.kt @@ -0,0 +1,10 @@ +package com.example.abe.data.network + +data class LoginRequest ( + val email: String, + val password: String +) + +data class LoginResponse ( + val token: String +) \ No newline at end of file diff --git a/app/src/main/java/com/example/abe/services/auth.kt b/app/src/main/java/com/example/abe/services/auth.kt new file mode 100644 index 0000000000000000000000000000000000000000..df0ba8ae47e580e0b3e97c48cad180fb79426873 --- /dev/null +++ b/app/src/main/java/com/example/abe/services/auth.kt @@ -0,0 +1,12 @@ +package com.example.abe.services + +import com.example.abe.types.LoginRequest +import com.example.abe.types.LoginResponse +import retrofit2.Call +import retrofit2.http.Body +import retrofit2.http.POST + +interface LoginService { + @POST("api/auth/login") + fun login(@Body user: LoginRequest) : Call<LoginResponse> +} \ No newline at end of file diff --git a/app/src/main/java/com/example/abe/types/data.kt b/app/src/main/java/com/example/abe/types/data.kt new file mode 100644 index 0000000000000000000000000000000000000000..103119b0f150af0030a88f6fd958bb97dc7a618b --- /dev/null +++ b/app/src/main/java/com/example/abe/types/data.kt @@ -0,0 +1,10 @@ +package com.example.abe.types + +data class LoginRequest ( + val email: String, + val password: String +) + +data class LoginResponse ( + val token: String +) \ No newline at end of file diff --git a/app/src/main/java/com/example/abe/ui/login/LoginActivity.kt b/app/src/main/java/com/example/abe/ui/login/LoginActivity.kt new file mode 100644 index 0000000000000000000000000000000000000000..bf0db62a8dac306e38118300600b1a288645e12a --- /dev/null +++ b/app/src/main/java/com/example/abe/ui/login/LoginActivity.kt @@ -0,0 +1,59 @@ +package com.example.abe.ui.login + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import com.example.abe.MainActivity +import com.example.abe.data.network.LoginResultCallback +import com.example.abe.data.network.Retrofit +import com.example.abe.databinding.ActivityLoginBinding +import com.example.abe.data.network.LoginResponse + +class LoginActivity : AppCompatActivity(), LoginResultCallback { + + private lateinit var binding: ActivityLoginBinding + + private val token = "" + + private fun attemptLogin(email: String, password: String) { + val retrofit = Retrofit() + retrofit.login(email, password, this) + } + + override fun onSuccess(loginResponse: com.example.abe.data.network.LoginResponse) { + // Handle successful login + println("Login successful: $loginResponse") + + val token = getSharedPreferences(token, Context.MODE_PRIVATE) + with(token.edit()) { + putString("login_token", loginResponse.token) + apply() + } + + val intent = Intent(this, MainActivity::class.java) + startActivity(intent) + } + + override fun onFailure(errorMessage: String) { + // Handle login failure + println(errorMessage) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityLoginBinding.inflate(layoutInflater) + + supportActionBar?.hide() + + val view = binding.root + setContentView(view) + + binding.btnSignIn.setOnClickListener { + val email: String = binding.emailInput.text.toString() + val password: String = binding.passwordInput.text.toString() + + attemptLogin(email, password) + } + } +} diff --git a/app/src/main/res/font/carter_one.ttf b/app/src/main/res/font/carter_one.ttf new file mode 100644 index 0000000000000000000000000000000000000000..0dc88516e190a0a27a9c2396ad19a25e00c78b52 Binary files /dev/null and b/app/src/main/res/font/carter_one.ttf differ diff --git a/app/src/main/res/font/roboto_medium.ttf b/app/src/main/res/font/roboto_medium.ttf new file mode 100644 index 0000000000000000000000000000000000000000..6893acd256460c1f4471e57feb17cf7fb9436b84 Binary files /dev/null and b/app/src/main/res/font/roboto_medium.ttf differ diff --git a/app/src/main/res/font/roboto_thin.ttf b/app/src/main/res/font/roboto_thin.ttf new file mode 100644 index 0000000000000000000000000000000000000000..8e5d7911fc6d249956618ab2fe8902d369437f25 Binary files /dev/null and b/app/src/main/res/font/roboto_thin.ttf differ diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000000000000000000000000000000000000..ac3598da695e7e684b840dfb9651f3ea3e78925e --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,93 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:backgroundTint="#9759C4" + tools:context=".ui.login.LoginActivity"> + + <EditText + android:id="@+id/emailInput" + android:layout_width="300dp" + android:layout_height="wrap_content" + android:layout_marginBottom="16dp" + android:ems="10" + android:hint="Email" + android:inputType="textEmailAddress" + android:outlineAmbientShadowColor="#000000" + android:outlineProvider="background" + android:visibility="visible" + app:layout_constraintBottom_toTopOf="@+id/passwordInput" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/appName" + app:layout_constraintVertical_bias="0.5" + app:layout_constraintVertical_chainStyle="packed" + tools:visibility="visible" /> + + <EditText + android:id="@+id/passwordInput" + android:layout_width="300dp" + android:layout_height="wrap_content" + android:ems="10" + android:hint="Password" + android:inputType="textPassword" + app:layout_constraintBottom_toTopOf="@+id/btnSignIn" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/emailInput" + app:layout_constraintVertical_bias="0.5" /> + + <Button + android:id="@+id/btnSignIn" + android:layout_width="300dp" + android:layout_height="wrap_content" + android:layout_marginTop="36dp" + android:background="#9759C4" + android:clickable="true" + android:text="Sign in" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/passwordInput" + app:layout_constraintVertical_bias="0.5" /> + + <TextView + android:id="@+id/welcomeText" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="8dp" + android:fontFamily="@font/roboto_medium" + android:text="Welcome back to" + android:textColor="#000000" + android:textSize="20sp" + app:layout_constraintBottom_toTopOf="@+id/appName" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_bias="0.5" + app:layout_constraintVertical_chainStyle="packed" /> + + <TextView + android:id="@+id/appName" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:layout_marginBottom="64dp" + android:fontFamily="@font/carter_one" + android:text="Bondoman" + android:textColor="#9759C4" + android:textSize="24sp" + android:textStyle="bold" + app:layout_constraintBottom_toTopOf="@+id/emailInput" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/welcomeText" + app:layout_constraintVertical_bias="0.5" /> +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml index 2fec919e09ef8f2362f100b56b2bc785531c8f29..02b6fe7217c5c6f8df77bfb94dbf203ba1622056 100644 --- a/app/src/main/res/values-night/themes.xml +++ b/app/src/main/res/values-night/themes.xml @@ -13,4 +13,18 @@ <item name="android:statusBarColor">?attr/colorPrimaryVariant</item> <!-- Customize your theme here. --> </style> + + <style name="Theme.ABE.login" parent="Theme.MaterialComponents.DayNight.NoActionBar"> + <!-- Primary brand color. --> + <item name="colorPrimary">@color/primary</item> + <item name="colorPrimaryVariant">@color/primaryActive</item> + <item name="colorOnPrimary">@color/white</item> + <!-- Secondary brand color. --> + <item name="colorSecondary">@color/secondary</item> + <item name="colorSecondaryVariant">@color/secondaryActive</item> + <item name="colorOnSecondary">@color/black</item> + <!-- Status bar color. --> + <item name="android:statusBarColor">?attr/colorPrimaryVariant</item> + <!-- Customize your theme here. --> + </style> </resources> \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 2dc53aca4b7cd115b4cae351d005b294ad4148b7..591d7143599a65ddec3ce4fd908251d8ecc8dd77 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -10,4 +10,7 @@ <color name="grayLight">#F5F5F8</color> <color name="black">#090909</color> <color name="white">#FFFFFFFF</color> + <color name="purple_700">#8346AA</color> + <color name="purple_200">#9759C4</color> + <color name="teal_200">#80CBC4</color> </resources> \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 46de546ab99e49df2e527534e24ab1c0356f0348..b4d5ee770b1d023748e696eb5dda776f3c184a16 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -13,4 +13,4 @@ <item name="android:statusBarColor">?attr/colorPrimaryVariant</item> <!-- Customize your theme here. --> </style> -</resources> \ No newline at end of file +</resources> diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7b9b29988b06b613b5cc643b051e38684c333864..2656043298a7d533934073d1a16cd7c42d68e82d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -18,6 +18,8 @@ roomCompiler = "2.6.1" legacySupportV4 = "1.0.0" fragmentKtx = "1.6.2" roomKtx = "2.6.1" +retrofit = "2.9.0" +gson = "2.9.0" poi = "5.2.5" poiOoxml = "5.2.5" @@ -39,6 +41,8 @@ androidx-room-compiler = { group = "androidx.room", name = "room-compiler", vers androidx-legacy-support-v4 = { group = "androidx.legacy", name = "legacy-support-v4", version.ref = "legacySupportV4" } androidx-fragment-ktx = { group = "androidx.fragment", name = "fragment-ktx", version.ref = "fragmentKtx" } androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "roomKtx" } +androidx-retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit"} +androidx-retrofit-gson = { group = "com.squareup.retrofit2", name = "converter-gson", version.ref = "gson" } poi = { group = "org.apache.poi", name = "poi", version.ref = "poi" } poi-ooxml = { group = "org.apache.poi", name = "poi-ooxml", version.ref = "poiOoxml" }