Bladeren bron

Worked on login screen, created UI for that

Khubaib 5 maanden geleden
bovenliggende
commit
bf6516d63c

+ 316 - 34
app/src/main/java/com/fastest/pass/login/presentation/components/LoginScreen.kt

@@ -1,13 +1,19 @@
 package com.fastest.pass.login.presentation.components
 
+import android.content.Intent
+import android.location.Location
+import android.util.Log
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.BoxScope
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.ColumnScope
 import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxHeight
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
@@ -18,24 +24,50 @@ import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.layout.statusBarsPadding
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.foundation.text.KeyboardActions
+import androidx.compose.foundation.text.KeyboardOptions
+import androidx.compose.material.icons.Icons
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
 import androidx.compose.material3.Icon
 import androidx.compose.material3.IconButton
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Surface
 import androidx.compose.material3.Text
+import androidx.compose.material3.TextField
+import androidx.compose.material3.TextFieldDefaults
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clip
+import androidx.compose.ui.focus.FocusManager
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ColorFilter
 import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.LocalFocusManager
+import androidx.compose.ui.platform.LocalSoftwareKeyboardController
+import androidx.compose.ui.platform.SoftwareKeyboardController
 import androidx.compose.ui.res.colorResource
 import androidx.compose.ui.res.painterResource
 import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.res.vectorResource
+import androidx.compose.ui.text.input.ImeAction
+import androidx.compose.ui.text.input.KeyboardType
+import androidx.compose.ui.text.input.PasswordVisualTransformation
+import androidx.compose.ui.text.input.VisualTransformation
+import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
+import androidx.lifecycle.viewmodel.compose.viewModel
 import androidx.navigation.NavHostController
 import com.fastest.pass.R
+import kotlinx.coroutines.launch
 
 @Composable
 fun LoginScreen() {
@@ -45,43 +77,14 @@ fun LoginScreen() {
             .fillMaxSize()
             .statusBarsPadding()
     ) {
-        
         Column(
             modifier = Modifier
                 .fillMaxSize()
-                .padding(top = 30.dp)
+                .padding(top = 0.dp)
                 .statusBarsPadding()
         ) {
             ShowHeaderLogin(text = stringResource(R.string.login))
-
-            Column(
-                modifier = Modifier
-                    .fillMaxSize()
-                    .padding(top = 30.dp)
-                    .statusBarsPadding()
-                    .background(
-                        colorResource(id = R.color.light_gray_login),
-                    )
-            ) {
-                Text(
-                    text = stringResource(id = R.string.master_password_required),
-                    color = colorResource(id = R.color.gray_splash),
-                    style = MaterialTheme.typography.displayLarge.copy(
-                        fontSize = 24.sp
-                    ),
-                    modifier = Modifier.align(Alignment.CenterHorizontally)
-                )
-                Text(
-                    text = stringResource(id = R.string.enter_master_password),
-                    color = colorResource(id = R.color.gray_splash),
-                    style = MaterialTheme.typography.displayLarge.copy(
-                        fontSize = 15.sp
-                    ),
-                    lineHeight = 20.sp,
-                    modifier = Modifier.align(Alignment.CenterHorizontally)
-                )
-            }
-
+            ShowWelcomeText()
         }
     }
 }
@@ -101,10 +104,9 @@ fun ColumnScope.ShowHeaderLogin(text: String) {
                 .padding(start = 30.dp)
                 .size(24.dp, 24.dp)
         ) {
-            Icon(
-                painter = painterResource(id = R.drawable.backarrow3x),
+            Image(
+                painter = painterResource(id = R.drawable.arrow_left),
                 contentDescription = "Arrow-Back",
-                tint = colorResource(id = R.color.white),
                 modifier = Modifier.size(24.dp, 24.dp)
             )
         }
@@ -122,4 +124,284 @@ fun ColumnScope.ShowHeaderLogin(text: String) {
             )
         }
     }
+}
+
+@Composable
+fun ColumnScope.ShowWelcomeText() {
+    val keyboardController = LocalSoftwareKeyboardController.current
+    val focusManager = LocalFocusManager.current
+
+    Column(
+        modifier = Modifier
+            .fillMaxSize()
+            .padding(top = 25.dp)
+            .clip(RoundedCornerShape(topStart = 35.dp, topEnd = 35.dp))
+            .background(
+                colorResource(id = R.color.light_gray_login),
+            )
+    ) {
+        Text(
+            text = stringResource(id = R.string.master_password_required),
+            color = colorResource(id = R.color.gray_splash),
+            style = MaterialTheme.typography.headlineLarge.copy(
+                fontSize = 26.sp
+            ),
+            lineHeight = 20.sp,
+            modifier = Modifier
+                .align(Alignment.Start)
+                .padding(start = 30.dp, top = 35.dp)
+        )
+        Text(
+            text = stringResource(id = R.string.enter_master_password),
+            color = colorResource(id = R.color.gray_splash),
+            style = MaterialTheme.typography.displayLarge.copy(
+                fontSize = 18.sp
+            ),
+            lineHeight = 25.sp,
+            modifier = Modifier
+                .align(Alignment.Start)
+                .padding(start = 30.dp, top = 5.dp, end = 50.dp)
+
+        )
+
+        LoginTextField(keyboardController, focusManager)
+        Spacer(modifier = Modifier.height(20.dp))
+        PasswordTextField(keyboardController, focusManager)
+        Spacer(modifier = Modifier.height(25.dp))
+        LoginButton()
+        ForgotPasswordText()
+        CreateAccountText()
+    }
+}
+
+@Composable
+fun ColumnScope.LoginTextField(
+    keyboardController: SoftwareKeyboardController?,
+    focusManager: FocusManager
+) {
+    var emailText by remember { mutableStateOf("") }
+
+    TextField(
+        value = emailText,
+        onValueChange = {
+            emailText = it
+        },
+        textStyle = MaterialTheme.typography.bodyMedium,
+        modifier = Modifier
+            .padding(start = 30.dp, end = 30.dp, top = 50.dp)
+            .align(Alignment.Start)
+            .fillMaxWidth()
+            .height(60.dp)
+            .border(
+                1.dp,
+                color = colorResource(id = R.color.gray_border_textfield),
+                shape = RoundedCornerShape(16.dp)
+            )
+            .background(color = colorResource(id = R.color.transparent)),
+        shape = RoundedCornerShape(16.dp),
+        placeholder = {
+            Text(
+                text = "Enter email address",
+                color = colorResource(id = R.color.gray_splash))
+        },
+//        label = {
+//            Text(text = context.getString(R.string.email),
+//                style = MaterialTheme.typography.customTypography.bodySmall
+//            )
+//        },
+        leadingIcon = {
+            Image(
+                painter = painterResource(id = R.drawable.profile_circle),
+                contentDescription = "Email Logo",
+                modifier = Modifier
+                    .size(24.dp, 24.dp)
+            )
+        },
+        maxLines = 1,
+        colors = TextFieldDefaults.colors(
+            focusedLabelColor = colorResource(id = R.color.gray_splash),
+            unfocusedContainerColor = colorResource(id = R.color.transparent),
+            focusedContainerColor = colorResource(id = R.color.transparent),
+            focusedIndicatorColor = colorResource(id = R.color.transparent),
+            disabledIndicatorColor = colorResource(id = R.color.transparent),
+            unfocusedIndicatorColor = colorResource(id = R.color.transparent),
+            cursorColor = colorResource(id = R.color.gray_splash),
+            ),
+        keyboardOptions = KeyboardOptions(
+            keyboardType = KeyboardType.Email,
+            imeAction = ImeAction.Done
+        ),
+        keyboardActions = KeyboardActions(
+            onDone = {
+                focusManager.clearFocus()
+                keyboardController?.hide()
+            }
+        ),
+    )
+}
+
+@Composable
+fun ColumnScope.PasswordTextField(
+    keyboardController: SoftwareKeyboardController?,
+    focusManager: FocusManager
+) {
+    var passwordText by remember { mutableStateOf("") }
+    var passwordVisible by remember { mutableStateOf(false) }
+
+    TextField(
+        value = passwordText,
+        onValueChange = {
+            passwordText = it
+        },
+        textStyle = MaterialTheme.typography.bodyMedium,
+        modifier = Modifier
+            .padding(start = 30.dp, end = 30.dp)
+            .align(Alignment.Start)
+            .fillMaxWidth()
+            .height(60.dp)
+            .border(
+                1.dp,
+                color = colorResource(id = R.color.gray_border_textfield),
+                shape = RoundedCornerShape(16.dp)
+            )
+            .background(color = colorResource(id = R.color.transparent)),
+                shape = RoundedCornerShape(16.dp),
+                placeholder = {
+                    Text(text = "Enter password",
+                        color = colorResource(id = R.color.gray_splash))
+                },
+//        label = {
+//            Text(text = context.getString(R.string.password),
+//                style = MaterialTheme.typography.customTypography.bodyLarge
+//            )
+//        },
+        maxLines = 1,
+        colors = TextFieldDefaults.colors(
+            focusedLabelColor = colorResource(id = R.color.gray_splash),
+            unfocusedContainerColor = colorResource(id = R.color.transparent),
+            focusedContainerColor = colorResource(id = R.color.transparent),
+            focusedIndicatorColor = colorResource(id = R.color.transparent),
+            disabledIndicatorColor = colorResource(id = R.color.transparent),
+            unfocusedIndicatorColor = colorResource(id = R.color.transparent),
+            cursorColor = colorResource(id = R.color.gray_splash),
+        ),
+        keyboardOptions = KeyboardOptions(
+            keyboardType = KeyboardType.Password,
+            imeAction = ImeAction.Done
+        ),
+        keyboardActions = KeyboardActions(
+            onDone = {
+                focusManager.clearFocus()
+                keyboardController?.hide()
+            }
+        ),
+        visualTransformation =
+        if (passwordVisible) VisualTransformation.Companion.None
+        else PasswordVisualTransformation(),
+
+        trailingIcon = {
+            val description = if (passwordVisible) "Hide Password"
+            else "Show Password"
+
+            IconButton(onClick = {
+                passwordVisible = !passwordVisible
+            })
+            {
+                if (passwordVisible) {
+                    Image(
+                        painter = painterResource(id = R.drawable.eye_open),
+                        contentDescription = description,
+                        modifier = Modifier.size(24.dp)
+                    )
+                }
+                else {
+                    Image(
+                        painter = painterResource(id = R.drawable.eye_slash3x),
+                        contentDescription = description,
+                        modifier = Modifier
+                            .size(24.dp),
+                        colorFilter = ColorFilter.tint(
+                            colorResource(id = R.color.gray_splash)
+                        )
+                    )
+                }
+            }
+        }
+    )
+}
+
+@Composable
+fun ColumnScope.LoginButton() {
+    Button(
+        modifier = Modifier
+            .padding(start = 30.dp, end = 30.dp,)
+            .background(colorResource(id = R.color.transparent))
+            .fillMaxWidth()
+            .height(60.dp)
+            .clickable() { },
+        onClick = {},
+        shape = RoundedCornerShape(15.dp),
+//            border = BorderStroke(25.dp, colorResource(id = R.color.black)),
+        colors = ButtonDefaults.buttonColors(
+            contentColor = colorResource(id = R.color.white),
+            containerColor = colorResource(id = R.color.red_login_button),
+        ),
+    )
+    {
+        Text(
+            text = stringResource(R.string.login),
+            style = MaterialTheme.typography.bodyMedium.copy(
+                fontSize = 20.sp,
+                color = colorResource(id = R.color.white)
+            ),
+            textAlign = TextAlign.Center
+        )
+    }
+}
+
+@Composable
+fun ColumnScope.ForgotPasswordText() {
+    Text(
+        text = stringResource(id = R.string.forgot_your_password),
+        color = colorResource(id = R.color.sky_green),
+        style = MaterialTheme.typography.displayLarge.copy(
+            fontSize = 16.sp
+        ),
+        lineHeight = 25.sp,
+        modifier = Modifier
+            .align(Alignment.End)
+            .padding(start = 30.dp, top = 15.dp, end = 30.dp)
+    )
+}
+
+@Composable
+fun ColumnScope.CreateAccountText() {
+    Row(
+        modifier = Modifier
+            .fillMaxWidth()
+            .padding(top = 25.dp)
+            .padding(horizontal = 30.dp),
+        verticalAlignment = Alignment.CenterVertically,
+        horizontalArrangement = Arrangement.Center
+    ) {
+        Text(
+            text = stringResource(id = R.string.dont_have_account),
+            color = colorResource(id = R.color.gray_splash),
+            style = MaterialTheme.typography.displayLarge.copy(
+                fontSize = 16.sp
+            ),
+            lineHeight = 25.sp,
+            modifier = Modifier
+        )
+        Spacer(modifier = Modifier.width(3.dp))
+        Text(
+            text = stringResource(id = R.string.create_account),
+            color = colorResource(id = R.color.sky_green),
+            style = MaterialTheme.typography.displayLarge.copy(
+                fontSize = 16.sp
+            ),
+            lineHeight = 25.sp,
+            modifier = Modifier
+        )
+    }
 }

+ 2 - 2
app/src/main/java/com/fastest/pass/ui/theme/Type.kt

@@ -57,8 +57,8 @@ val Typography = Typography(
     ),
     headlineLarge = TextStyle(
         fontFamily = outfitFontFamily,
-        fontWeight = FontWeight.Medium,
-        fontSize = 28.sp,
+        fontWeight = FontWeight.ExtraBold,
+        fontSize = 24.sp,
     ),
     titleSmall = TextStyle(
         fontFamily = outfitFontFamily,

+ 20 - 0
app/src/main/res/drawable/arrow_left.xml

@@ -0,0 +1,20 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="25dp"
+    android:viewportWidth="24"
+    android:viewportHeight="25">
+  <path
+      android:pathData="M9.57,6.43L3.5,12.5L9.57,18.57"
+      android:strokeLineJoin="round"
+      android:strokeWidth="1.5"
+      android:fillColor="#00000000"
+      android:strokeColor="#ffffff"
+      android:strokeLineCap="round"/>
+  <path
+      android:pathData="M20.5,12.5H3.67"
+      android:strokeLineJoin="round"
+      android:strokeWidth="1.5"
+      android:fillColor="#00000000"
+      android:strokeColor="#ffffff"
+      android:strokeLineCap="round"/>
+</vector>

+ 20 - 0
app/src/main/res/drawable/eye_open.xml

@@ -0,0 +1,20 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="25dp"
+    android:viewportWidth="24"
+    android:viewportHeight="25">
+  <path
+      android:pathData="M15.58,12.407C15.58,14.387 13.98,15.987 12,15.987C10.02,15.987 8.42,14.387 8.42,12.407C8.42,10.427 10.02,8.827 12,8.827C13.98,8.827 15.58,10.427 15.58,12.407Z"
+      android:strokeLineJoin="round"
+      android:strokeWidth="1.5"
+      android:fillColor="#00000000"
+      android:strokeColor="#404B69"
+      android:strokeLineCap="round"/>
+  <path
+      android:pathData="M12,20.677C15.53,20.677 18.82,18.597 21.11,14.997C22.01,13.587 22.01,11.217 21.11,9.807C18.82,6.207 15.53,4.127 12,4.127C8.47,4.127 5.18,6.207 2.89,9.807C1.99,11.217 1.99,13.587 2.89,14.997C5.18,18.597 8.47,20.677 12,20.677Z"
+      android:strokeLineJoin="round"
+      android:strokeWidth="1.5"
+      android:fillColor="#00000000"
+      android:strokeColor="#404B69"
+      android:strokeLineCap="round"/>
+</vector>

BIN
app/src/main/res/drawable/eye_slash3x.png


+ 27 - 0
app/src/main/res/drawable/profile_circle.xml

@@ -0,0 +1,27 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="25dp"
+    android:viewportWidth="24"
+    android:viewportHeight="25">
+  <path
+      android:pathData="M12.12,13.187C12.05,13.177 11.96,13.177 11.88,13.187C10.12,13.127 8.72,11.687 8.72,9.917C8.72,8.107 10.18,6.637 12,6.637C13.81,6.637 15.28,8.107 15.28,9.917C15.27,11.687 13.88,13.127 12.12,13.187Z"
+      android:strokeLineJoin="round"
+      android:strokeWidth="1.5"
+      android:fillColor="#00000000"
+      android:strokeColor="#404B69"
+      android:strokeLineCap="round"/>
+  <path
+      android:pathData="M18.74,19.787C16.96,21.417 14.6,22.407 12,22.407C9.4,22.407 7.04,21.417 5.26,19.787C5.36,18.847 5.96,17.927 7.03,17.207C9.77,15.387 14.25,15.387 16.97,17.207C18.04,17.927 18.64,18.847 18.74,19.787Z"
+      android:strokeLineJoin="round"
+      android:strokeWidth="1.5"
+      android:fillColor="#00000000"
+      android:strokeColor="#404B69"
+      android:strokeLineCap="round"/>
+  <path
+      android:pathData="M12,22.407C17.523,22.407 22,17.93 22,12.407C22,6.885 17.523,2.407 12,2.407C6.477,2.407 2,6.885 2,12.407C2,17.93 6.477,22.407 12,22.407Z"
+      android:strokeLineJoin="round"
+      android:strokeWidth="1.5"
+      android:fillColor="#00000000"
+      android:strokeColor="#404B69"
+      android:strokeLineCap="round"/>
+</vector>

+ 3 - 0
app/src/main/res/values/colors.xml

@@ -11,5 +11,8 @@
     <color name="blue_login">#283149</color>
     <color name="light_gray_login">#DBEDF3</color>
     <color name="transparent">#00000000</color>
+    <color name="gray_border_textfield">#FFA7B1C6</color>
+    <color name="red_login_button">#FFD83F31</color>
+    <color name="sky_green">#FF1EAE98</color>
 
 </resources>

+ 3 - 0
app/src/main/res/values/strings.xml

@@ -3,4 +3,7 @@
     <string name="login">Log In</string>
     <string name="master_password_required">Master password required</string>
     <string name="enter_master_password">Hello! Please enter your master password to continue.</string>
+    <string name="forgot_your_password">Forgot your password?</string>
+    <string name="dont_have_account">Don\'t have an account?</string>
+    <string name="create_account">Create Account</string>
 </resources>