From 4de7143c5190c7bd9459a7d746757c10c0c8b022 Mon Sep 17 00:00:00 2001 From: 0xzre <alilo.ghazali@gmail.com> Date: Fri, 15 Mar 2024 14:40:26 +0700 Subject: [PATCH] feat login n jwt checker bg --- app/build.gradle.kts | 2 + app/src/main/AndroidManifest.xml | 11 +- .../java/com/atm/bondowowo/BondowowoApp.kt | 41 +++++++ .../java/com/atm/bondowowo/LoginActivity.kt | 107 ++++++++++++++++++ .../java/com/atm/bondowowo/MainActivity.kt | 65 +++++++++-- .../atm/bondowowo/data/model/LoginRequest.kt | 6 + .../atm/bondowowo/data/model/LoginResponse.kt | 5 + .../bondowowo/data/model/VerifyResponse.kt | 7 ++ .../atm/bondowowo/data/remote/ApiService.kt | 17 +++ .../utils/BackgroundJWTCheckerUtil.kt | 50 ++++++++ .../com/atm/bondowowo/utils/NetworkUtils.kt | 16 +++ .../main/res/color/bottom_nav_icon_color.xml | 5 + .../main/res/color/bottom_nav_text_color.xml | 5 + app/src/main/res/drawable/ic_logo.png | Bin 0 -> 15652 bytes app/src/main/res/drawable/ic_scan.png | Bin 586 -> 849 bytes app/src/main/res/layout/activity_login.xml | 66 +++++++++++ .../res/layout/bottom_navigation_layout.xml | 7 +- app/src/main/res/values/colors.xml | 6 + app/src/main/res/values/styles.xml | 14 +++ 19 files changed, 414 insertions(+), 16 deletions(-) create mode 100644 app/src/main/java/com/atm/bondowowo/BondowowoApp.kt create mode 100644 app/src/main/java/com/atm/bondowowo/LoginActivity.kt create mode 100644 app/src/main/java/com/atm/bondowowo/data/model/LoginRequest.kt create mode 100644 app/src/main/java/com/atm/bondowowo/data/model/LoginResponse.kt create mode 100644 app/src/main/java/com/atm/bondowowo/data/model/VerifyResponse.kt create mode 100644 app/src/main/java/com/atm/bondowowo/data/remote/ApiService.kt create mode 100644 app/src/main/java/com/atm/bondowowo/utils/BackgroundJWTCheckerUtil.kt create mode 100644 app/src/main/java/com/atm/bondowowo/utils/NetworkUtils.kt create mode 100644 app/src/main/res/color/bottom_nav_icon_color.xml create mode 100644 app/src/main/res/color/bottom_nav_text_color.xml create mode 100644 app/src/main/res/drawable/ic_logo.png create mode 100644 app/src/main/res/layout/activity_login.xml create mode 100644 app/src/main/res/values/styles.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 9adfcd8..1c1e372 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -48,6 +48,8 @@ dependencies { implementation("androidx.navigation:navigation-fragment-ktx:$navVersion") implementation("androidx.navigation:navigation-ui-ktx:$navVersion") implementation("com.google.android.material:material:1.9.0") + implementation("com.squareup.retrofit2:retrofit:2.9.0") + implementation("com.squareup.retrofit2:converter-gson:2.9.0") testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.1.5") androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e105b0d..8beb467 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,7 +2,10 @@ <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=".BondowowoApp" android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" @@ -14,8 +17,12 @@ tools:targetApi="31"> <activity android:name=".MainActivity" - android:label="@string/app_name" - android:exported="true"> + android:exported="false" + android:theme="@style/AppTheme.NoActionBar"/> + <activity + android:name=".LoginActivity" + android:exported="true" + android:theme="@style/AppTheme.NoActionBar"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> diff --git a/app/src/main/java/com/atm/bondowowo/BondowowoApp.kt b/app/src/main/java/com/atm/bondowowo/BondowowoApp.kt new file mode 100644 index 0000000..c52591a --- /dev/null +++ b/app/src/main/java/com/atm/bondowowo/BondowowoApp.kt @@ -0,0 +1,41 @@ +package com.atm.bondowowo; + +import android.app.Activity +import android.app.Application +import android.content.Context +import android.content.Intent +import com.atm.bondowowo.utils.BackgroundJWTChecker + +class BondowowoApp : Application() { + + private var jwtChecker: BackgroundJWTChecker? = null + + override fun onCreate() { + super.onCreate() + initBackgroundJWTChecker(this) + } + + private fun initBackgroundJWTChecker(context: Context) { + jwtChecker = BackgroundJWTChecker() + jwtChecker?.startChecking(context, object : BackgroundJWTChecker.Callback { + override fun onTokenVerified() { + // Continu app + } + + override fun onTokenInvalid() { + val intent = Intent(context, LoginActivity::class.java) + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + context.startActivity(intent) + if (context is Activity) { + context.finish() + } + } + + override fun onNetworkError() { + // Harusnya ini coba cek isi JWT pake library + } + }) + } + + +} diff --git a/app/src/main/java/com/atm/bondowowo/LoginActivity.kt b/app/src/main/java/com/atm/bondowowo/LoginActivity.kt new file mode 100644 index 0000000..bdb2521 --- /dev/null +++ b/app/src/main/java/com/atm/bondowowo/LoginActivity.kt @@ -0,0 +1,107 @@ +package com.atm.bondowowo + +import android.content.Intent +import android.os.Bundle +import android.widget.Button +import android.widget.EditText +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import com.atm.bondowowo.data.model.LoginRequest +import com.atm.bondowowo.utils.NetworkUtils.apiService +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class LoginActivity : AppCompatActivity() { + + private lateinit var etUsername: EditText + private lateinit var etPassword: EditText + private lateinit var btnLogin: Button + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_login) + + CoroutineScope(Dispatchers.Main).launch { + if (isUserAuthenticated()) { + navigateToMainActivity() + } else { + etUsername = findViewById(R.id.etUsername) + etPassword = findViewById(R.id.etPassword) + btnLogin = findViewById(R.id.btnLogin) + + btnLogin.setOnClickListener { + performLogin() + } + } + } + } + + private fun performLogin() { + val email = etUsername.text.toString() + val password = etPassword.text.toString() + + val loginRequest = LoginRequest(email, password) + + CoroutineScope(Dispatchers.IO).launch { + try { + val response = apiService.login(loginRequest) + if (response.isSuccessful) { + val loginResponse = response.body() + val token = loginResponse?.token + + saveTokenSecurely(token) + + startActivity(Intent(this@LoginActivity, MainActivity::class.java)) + finish() + } else { + withContext(Dispatchers.Main) { + Toast.makeText(this@LoginActivity, "Invalid Credentials", Toast.LENGTH_SHORT) + .show() + } + } + } catch (e: Exception) { + withContext(Dispatchers.Main) { + Toast.makeText(this@LoginActivity, "An error occurred", Toast.LENGTH_SHORT) + .show() + } + } + } + } + + private fun saveTokenSecurely(token: String?) { + val sharedPreferences = getSharedPreferences("AUTH_PREFS", MODE_PRIVATE) + val editor = sharedPreferences.edit() + editor.putString("JWT_TOKEN", token) + editor.apply() + } + + private suspend fun isUserAuthenticated(): Boolean { + val sharedPreferences = getSharedPreferences("AUTH_PREFS", MODE_PRIVATE) + val token = sharedPreferences.getString("JWT_TOKEN", null) + val isValid = token?.let { isTokenValid(it) } + + return token != null && isValid == true + } + + private fun navigateToMainActivity() { + startActivity(Intent(this, MainActivity::class.java)) + finish() + } + + private suspend fun isTokenValid(token: String): Boolean { + return try { + val response = apiService.verifyToken("Bearer $token") + if (response.isSuccessful) { + val responseBody = response.body() + val isString = responseBody is String + return !isString + } else { + false + } + } catch (e: Exception) { + false + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/atm/bondowowo/MainActivity.kt b/app/src/main/java/com/atm/bondowowo/MainActivity.kt index 2a4bb99..8c31aac 100644 --- a/app/src/main/java/com/atm/bondowowo/MainActivity.kt +++ b/app/src/main/java/com/atm/bondowowo/MainActivity.kt @@ -1,13 +1,17 @@ package com.atm.bondowowo +import android.content.Intent import android.os.Bundle +import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.navigation.findNavController import androidx.navigation.fragment.NavHostFragment -import androidx.navigation.ui.AppBarConfiguration -import androidx.navigation.ui.setupActionBarWithNavController import androidx.navigation.ui.setupWithNavController import com.atm.bondowowo.databinding.ActivityMainBinding +import com.atm.bondowowo.utils.NetworkUtils +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch class MainActivity : AppCompatActivity() { @@ -18,20 +22,57 @@ class MainActivity : AppCompatActivity() { binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) - // Navigation Component - val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment - val navController = navHostFragment.navController - val appBarConfiguration = AppBarConfiguration( - setOf( - R.id.transactionFragment, R.id.scanFragment, R.id.graphFragment, R.id.settingsFragment - ) - ) - setupActionBarWithNavController(navController, appBarConfiguration) - binding.bottomNavLayout.bottomNavigation.setupWithNavController(navController) + CoroutineScope(Dispatchers.Main).launch { + if (!isUserAuthenticated()) { + navigateToLoginActivity() + } else { + val navHostFragment = + supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment + val navController = navHostFragment.navController + binding.bottomNavLayout.bottomNavigation.setupWithNavController(navController) + } + } } override fun onSupportNavigateUp(): Boolean { val navController = findNavController(R.id.nav_host_fragment) return navController.navigateUp() || super.onSupportNavigateUp() } + + private suspend fun isUserAuthenticated(): Boolean { + val sharedPreferences = getSharedPreferences("AUTH_PREFS", MODE_PRIVATE) + val token = sharedPreferences.getString("JWT_TOKEN", null) + + return token != null && isTokenValid(token) + } + + private fun navigateToLoginActivity() { + startActivity(Intent(this, LoginActivity::class.java)) + finish() + } + + private suspend fun isTokenValid(token: String): Boolean { + return try { + val response = NetworkUtils.apiService.verifyToken("Bearer $token") + if (response.isSuccessful) { + val responseBody = response.body() + val isString = responseBody is String + return !isString + } else { + Toast.makeText( + this@MainActivity, + "Session Expired, Please Re login", + Toast.LENGTH_SHORT + ).show() + false + } + } catch (e: Exception) { + Toast.makeText( + this@MainActivity, + "An error occurred, Please Re login", + Toast.LENGTH_SHORT + ).show() + false + } + } } diff --git a/app/src/main/java/com/atm/bondowowo/data/model/LoginRequest.kt b/app/src/main/java/com/atm/bondowowo/data/model/LoginRequest.kt new file mode 100644 index 0000000..f3aedb6 --- /dev/null +++ b/app/src/main/java/com/atm/bondowowo/data/model/LoginRequest.kt @@ -0,0 +1,6 @@ +package com.atm.bondowowo.data.model + +data class LoginRequest( + val email: String, + val password: String +) \ No newline at end of file diff --git a/app/src/main/java/com/atm/bondowowo/data/model/LoginResponse.kt b/app/src/main/java/com/atm/bondowowo/data/model/LoginResponse.kt new file mode 100644 index 0000000..4d9a220 --- /dev/null +++ b/app/src/main/java/com/atm/bondowowo/data/model/LoginResponse.kt @@ -0,0 +1,5 @@ +package com.atm.bondowowo.data.model + +data class LoginResponse( + val token: String // JWT +) \ No newline at end of file diff --git a/app/src/main/java/com/atm/bondowowo/data/model/VerifyResponse.kt b/app/src/main/java/com/atm/bondowowo/data/model/VerifyResponse.kt new file mode 100644 index 0000000..7d5e964 --- /dev/null +++ b/app/src/main/java/com/atm/bondowowo/data/model/VerifyResponse.kt @@ -0,0 +1,7 @@ +package com.atm.bondowowo.data.model + +data class VerifyResponse( + val nim: String, + val iat: Int, + val exp: Int +) diff --git a/app/src/main/java/com/atm/bondowowo/data/remote/ApiService.kt b/app/src/main/java/com/atm/bondowowo/data/remote/ApiService.kt new file mode 100644 index 0000000..a1a5440 --- /dev/null +++ b/app/src/main/java/com/atm/bondowowo/data/remote/ApiService.kt @@ -0,0 +1,17 @@ +package com.atm.bondowowo.data.remote + +import com.atm.bondowowo.data.model.LoginRequest +import com.atm.bondowowo.data.model.LoginResponse +import com.atm.bondowowo.data.model.VerifyResponse +import retrofit2.Response +import retrofit2.http.Body +import retrofit2.http.Header +import retrofit2.http.POST + +interface ApiService { + @POST("api/auth/login") + suspend fun login(@Body loginRequest: LoginRequest): Response<LoginResponse> + + @POST("api/auth/token") + suspend fun verifyToken(@Header("Authorization") jwtToken: String): Response<Any> +} diff --git a/app/src/main/java/com/atm/bondowowo/utils/BackgroundJWTCheckerUtil.kt b/app/src/main/java/com/atm/bondowowo/utils/BackgroundJWTCheckerUtil.kt new file mode 100644 index 0000000..5af4f8c --- /dev/null +++ b/app/src/main/java/com/atm/bondowowo/utils/BackgroundJWTCheckerUtil.kt @@ -0,0 +1,50 @@ +package com.atm.bondowowo.utils + +import androidx.appcompat.app.AppCompatActivity +import android.content.Context +import kotlinx.coroutines.* + +class BackgroundJWTChecker { + + private var job: Job? = null + + interface Callback { + fun onTokenVerified() + fun onTokenInvalid() + fun onNetworkError() + } + + @OptIn(DelicateCoroutinesApi::class) + fun startChecking(context: Context, callback: Callback) { + job = GlobalScope.launch(Dispatchers.IO) { + while (isActive) { + val sharedPreferences = context.getSharedPreferences( + "AUTH_PREFS", + AppCompatActivity.MODE_PRIVATE + ) + val token = sharedPreferences.getString("JWT_TOKEN", null) + if (token != null) { + verifyToken(token, callback) + } else { + callback.onTokenInvalid() + } + delay(3 * 60 * 1000) + } + } + } + + + private suspend fun verifyToken(token: String, callback: Callback) { + try { + val response = NetworkUtils.apiService.verifyToken("Bearer $token") + if (response.isSuccessful && response.body() !is String) { + callback.onTokenVerified() + } else { + callback.onTokenInvalid() + } + } catch (e: Exception) { + callback.onNetworkError() + } + } + +} diff --git a/app/src/main/java/com/atm/bondowowo/utils/NetworkUtils.kt b/app/src/main/java/com/atm/bondowowo/utils/NetworkUtils.kt new file mode 100644 index 0000000..41395da --- /dev/null +++ b/app/src/main/java/com/atm/bondowowo/utils/NetworkUtils.kt @@ -0,0 +1,16 @@ +package com.atm.bondowowo.utils + +// NetworkUtils.kt + +import com.atm.bondowowo.data.remote.ApiService +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory + +object NetworkUtils { + private val retrofit = Retrofit.Builder() + .baseUrl("https://pbd-backend-2024.vercel.app/") + .addConverterFactory(GsonConverterFactory.create()) + .build() + + val apiService: ApiService = retrofit.create(ApiService::class.java) +} diff --git a/app/src/main/res/color/bottom_nav_icon_color.xml b/app/src/main/res/color/bottom_nav_icon_color.xml new file mode 100644 index 0000000..ce755c1 --- /dev/null +++ b/app/src/main/res/color/bottom_nav_icon_color.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:color="@color/black" android:state_checked="true" /> + <item android:color="@color/grey" android:state_checked="false" /> +</selector> \ No newline at end of file diff --git a/app/src/main/res/color/bottom_nav_text_color.xml b/app/src/main/res/color/bottom_nav_text_color.xml new file mode 100644 index 0000000..ce755c1 --- /dev/null +++ b/app/src/main/res/color/bottom_nav_text_color.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:color="@color/black" android:state_checked="true" /> + <item android:color="@color/grey" android:state_checked="false" /> +</selector> \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_logo.png b/app/src/main/res/drawable/ic_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..ec727bb458122581b1579079bc02db305b2a7492 GIT binary patch literal 15652 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/ic_scan.png b/app/src/main/res/drawable/ic_scan.png index 5bc7a45d202c7b5f24ea36464b312bfd8d1eb3d1..cc17501d3eeb34b3eaf3cbd12d48561aa0145290 100644 GIT binary patch delta 812 zcmV+{1JnG<1knZ|iBL{Q4GJ0x0000DNk~Le0000U0000U2nGNE06Q?QqLCpqe*)%7 zL_t(|0qvJdPZLoT$N%Sc(6SLEVIeVs3865QhcTfKCGZhgxFQ-|xNxa_0NeTnU~OFM z#zfud!UcwB!5A>m7K}zJh=z@gaUqZ1<Cy|&XIhI57B>8nxpU{<GxvXI&Y8LA5(L#A zxXXkP7`1S~n);BK8bdjFeVwG$e+&q2TRY(^X*|^N=?8`~1NRw-h-iwL$3c|NsUjuH zUr;W(dV^^*>TD)W9wv^UE%1}5J+LYY2JdWM#`4@cDv9Sx0~tDIRh1m)<%yRnE^4tn zxelfUsnr^PH8Ooy<>fSIuQlFaDY}AEv;<mVus>5L@g}D~BR)HBvmws7f3m2s@&?1= z?~tw0g}3r%dQbwYq9=0d&Na9|W-y}TQ(>oVp|C_`MwAg_@YCENc#Q*K(2xXUU-lMK z0}@OjwDdf~huQabVa9J6G=JW8yMu^mJQ_wh#3o0j9L-L|^ouxkL8-HOvrAce63uBp zT<HxQ5v=(hs%XS;zJiLge;c4Hg+4ai^Sre+Ayb>hp`n+|=(2=x!f|2!t6#~v6-Nkx zqK160DcC>ciX#Dc1}7XJt^OtnxFpQrbsQEmc#YbFb1(yS&MsA8Y@kWX3$g$=<IrfY zgi<#&cNWTY1p2Ve$paVp|3zExIa%B56<L{u!U&ECQag_cJJH=me}Yhx>pJxb*tXWu zo02^=?zd{@7f4J$FEyw#{dc7F?O#h0(7#t*u^BR|3s<Mbu~qi^Bg7Pv8*gQ2O6Zo< zr=&1L4N6YcYinZ;7jt9rWN$GV=4Rg`xbu>|U+#Gvfc%keK=H-QMLMlvoL<1f#E)XO z#@<w21w9{U)}&lRe>o(kl2RuB#nk$oQsU1JcrG=d(pVAA<dNDMLH13uL=4Mge-}?K zIc-^Q4I=UG8_L1@2`L(upv~KhS-CEESo<?^NytEKdPIV$MuO?K^!D3TB?Hw)z0}GR quA)ZS01Ut}SZ03)9+K>J_z!9P4E^-_I6?pb002ovPDHLk0$_qz?sSU) delta 546 zcmV+-0^R-52Fe5>iBL{Q4GJ0x0000DNk~Le0000o0000o2nGNE03JVxv5_G(e*xb~ zL_t(|0qvSSO9Md=hF?EWk%)!%2DP`cu=0wO78W*kb|Qk7A_P)vA!;F7+KCAMfLH{v zv#_udqS0PRG&X`?Gu+8-F5a!KXeMMHcwsI#+1*Lzc5m($P?SHRE#`BNG*22Qbs(7v zX_vGIH<n1tq;`v6l~g3{kWTOof3l?aAF2#@9v%A2+8WI`G|D=JJ9)=GJ+qN$Y8{iN z1N(-wLb^vX52OqHj!DF)`6nsT7HK#*J|NA;IbR}-cnb2EK{&pmc_Mm&r40KC@-VZb zW)iZ^6itH$A`J~h8X8E0c#g5_$iZK1?nvE`M?a|qe~cS8=b_*WQt2h7f1xN!YZ5JH zc*a_V%&FIei@8nGZJfgy+{(^Is9+8}y0X8ZdFV6`qN$Z8%|Sl=kL)8MwG>5ZA;w4p zkPDX>6E-I<R(NVFL1s<T1Hb6wG3JsSuMn=B)~FkRhj4r)^F(xI?=o!Z_ggjSQxs`v zAkxr4q!A6|)vyO4k3Pe$c$z0VBaY{!k-%Pu|9rKIWZp=paEE_PzAdudN$?N5W*lE9 zIeT!cpYw3%$g$6itznl90~NSacIdBe!$91-ZH{)4G>Y0cy<fqp#qYnj;RbINS%5vY k`1<A4=dB_ID9Zov0r@o8pmxTXt^fc407*qoM6N<$f=>MNCjbBd 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 0000000..f4c3510 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,66 @@ +<?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" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:padding="23dp"> + + <ImageView + android:id="@+id/ivLogo" + android:layout_width="350dp" + android:layout_height="150dp" + android:layout_marginTop="80dp" + android:src="@drawable/ic_logo" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.466" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + android:contentDescription="Logo" /> + + <EditText + android:id="@+id/etUsername" + android:layout_width="0dp" + android:layout_height="60dp" + android:layout_marginTop="84dp" + android:hint="Enter your email" + android:inputType="text" + android:background="@color/textfield" + android:paddingStart="20dp" + android:paddingEnd="20dp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.0" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/ivLogo" + android:autofillHints="emailAddress" /> + + <EditText + android:id="@+id/etPassword" + android:layout_width="0dp" + android:layout_height="75dp" + android:layout_marginTop="16dp" + android:hint="Enter your password" + android:inputType="textPassword" + android:background="@color/textfield" + android:paddingStart="20dp" + android:paddingEnd="20dp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/etUsername" + android:autofillHints="password" /> + + <Button + android:id="@+id/btnLogin" + android:layout_width="0dp" + android:layout_height="70dp" + android:layout_marginTop="104dp" + android:backgroundTint="@color/primary1" + + android:text="Login" + android:textAllCaps="false" + android:textColor="#FFFFFF" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.0" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/etPassword" /> + +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/bottom_navigation_layout.xml b/app/src/main/res/layout/bottom_navigation_layout.xml index c31cae3..ea6f4c7 100644 --- a/app/src/main/res/layout/bottom_navigation_layout.xml +++ b/app/src/main/res/layout/bottom_navigation_layout.xml @@ -3,5 +3,8 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/bottomNavigation" android:layout_width="match_parent" - android:layout_height="wrap_content" - app:menu="@menu/bottom_navigation_menu" /> \ No newline at end of file + android:layout_height="70dp" + android:background="@color/white" + app:itemIconTint="@color/bottom_nav_icon_color" + app:itemTextColor="@color/bottom_nav_text_color" + app:menu="@menu/bottom_navigation_menu" /> diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index f8c6127..14750cd 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -7,4 +7,10 @@ <color name="teal_700">#FF018786</color> <color name="black">#FF000000</color> <color name="white">#FFFFFFFF</color> + <color name="grey">#808080</color> + <color name="primary1">#012B39</color> + <color name="primary2">#1F7A8C</color> + <color name="primary3">#C0DBF8</color> + <color name="textfield">#F7F8F9</color> + </resources> \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..9c62daf --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> + </style> + + <style name="AppTheme.NoActionBar"> + <item name="windowActionBar">false</item> + <item name="windowNoTitle">true</item> + <item name="colorPrimary">@color/white</item> + <item name="colorPrimaryDark">@color/primary1</item> + <item name="colorAccent">@color/primary2</item> + </style> +</resources> \ No newline at end of file -- GitLab