From 497957b183fef3651394ce0984e8237e8db4990f Mon Sep 17 00:00:00 2001 From: Karan Joshi Date: Wed, 16 Jul 2025 21:42:27 +0530 Subject: [PATCH 01/10] Theming in home/vault --- .../java/com/karan/hashin/MainActivity.kt | 2 +- .../com/karan/hashin/components/Element.kt | 44 +++++++++++++++---- .../{BottomAppBar.kt => NavigationBar.kt} | 40 +++++++++-------- .../com/karan/hashin/screens/home/Home.kt | 10 ++--- .../com/karan/hashin/screens/home/Vault.kt | 11 ++--- .../java/com/karan/hashin/ui/theme/Theme.kt | 14 ++++-- 6 files changed, 75 insertions(+), 46 deletions(-) rename app/src/main/java/com/karan/hashin/components/{BottomAppBar.kt => NavigationBar.kt} (85%) diff --git a/app/src/main/java/com/karan/hashin/MainActivity.kt b/app/src/main/java/com/karan/hashin/MainActivity.kt index 1f92e1e..38db257 100644 --- a/app/src/main/java/com/karan/hashin/MainActivity.kt +++ b/app/src/main/java/com/karan/hashin/MainActivity.kt @@ -18,7 +18,7 @@ class MainActivity : ComponentActivity() { enableEdgeToEdge() setContent { - HashinTheme { + HashinTheme(dynamicColor = false) { navController = rememberNavController() NavGraph(navController) } diff --git a/app/src/main/java/com/karan/hashin/components/Element.kt b/app/src/main/java/com/karan/hashin/components/Element.kt index e00b6a9..de91705 100644 --- a/app/src/main/java/com/karan/hashin/components/Element.kt +++ b/app/src/main/java/com/karan/hashin/components/Element.kt @@ -1,9 +1,11 @@ package com.karan.hashin.components +import android.content.res.Configuration import com.karan.hashin.R import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable +import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -15,6 +17,8 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -22,6 +26,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -37,7 +42,7 @@ fun Element( Card( colors = CardDefaults.cardColors( - containerColor = Color.White + containerColor = MaterialTheme.colorScheme.primaryContainer ), elevation = CardDefaults.cardElevation( defaultElevation = 4.dp @@ -54,12 +59,13 @@ fun Element( modifier = Modifier .fillMaxSize() ) { - Image( + Icon ( imageVector = ImageVector.vectorResource(id = R.drawable.people), contentDescription = "Element Icon Image", + tint = MaterialTheme.colorScheme.primary, modifier = Modifier .padding(start = 16.dp) - .size(52.dp) + .size(36.dp) ) Column( @@ -68,7 +74,7 @@ fun Element( ) { Text( text = passKey.service.ifEmpty { "Website" }, - fontSize = 22.sp, + fontSize = 20.sp, color = getColorForLabel(passKey.label) ) @@ -76,7 +82,7 @@ fun Element( text = passKey.userName, fontSize = 14.sp, modifier = Modifier - .padding(start = 4.dp) + .padding(start = 2.dp) ) } Spacer( @@ -92,7 +98,8 @@ fun Element( ) { Text( text = passKey.label.firstOrNull()?.uppercase() ?: "", - color = Color.White, + color = MaterialTheme.colorScheme.onPrimaryContainer, + fontWeight = FontWeight.W300, fontSize = 36.sp, ) } @@ -100,11 +107,30 @@ fun Element( } } -@Preview(showBackground = true, showSystemUi = true) +@Preview( + name = "Dark Theme", + showBackground = true, + showSystemUi = false, + uiMode = Configuration.UI_MODE_NIGHT_YES +) +@Preview( + name = "Light Theme", + showBackground = true, + showSystemUi = false, + uiMode = Configuration.UI_MODE_NIGHT_NO +) @Composable private fun PreviewElement() { - HashinTheme { - Element(PassKey("", "", "", ""), Modifier.padding(top = 144.dp)) {} + HashinTheme(dynamicColor = false) { + Element(PassKey( + service = "Github", + userName = "KaranJoshi1208", + desc = "My passkey", + label = "Work" + ), + modifier = Modifier, + onClick = {} + ) } } diff --git a/app/src/main/java/com/karan/hashin/components/BottomAppBar.kt b/app/src/main/java/com/karan/hashin/components/NavigationBar.kt similarity index 85% rename from app/src/main/java/com/karan/hashin/components/BottomAppBar.kt rename to app/src/main/java/com/karan/hashin/components/NavigationBar.kt index 3d4d039..caae26d 100644 --- a/app/src/main/java/com/karan/hashin/components/BottomAppBar.kt +++ b/app/src/main/java/com/karan/hashin/components/NavigationBar.kt @@ -1,26 +1,23 @@ package com.karan.hashin.components import android.content.res.Configuration -import com.karan.hashin.ui.theme.iconTintDark -import androidx.compose.ui.graphics.Color -import com.karan.hashin.R import androidx.compose.foundation.background +import androidx.compose.runtime.getValue +import com.karan.hashin.ui.theme.iconTintDark import androidx.compose.foundation.border import androidx.compose.foundation.clickable -import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.navigationBarsPadding -import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Key -import androidx.compose.material.icons.outlined.Settings import androidx.compose.material.icons.rounded.Add import androidx.compose.material.icons.rounded.Settings import androidx.compose.material3.Card @@ -28,29 +25,26 @@ import androidx.compose.material3.CardDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.RectangleShape -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.vectorResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.semantics import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.karan.hashin.ui.theme.HashinTheme -import com.karan.hashin.ui.theme.PurpleA700 -import com.karan.hashin.ui.theme.iconTintLight @Composable -fun BottomAppBar( +fun NavigationBar( toVault: () -> Unit = {}, toPassKey: () -> Unit = {}, toSetting: () -> Unit = {}, selection: Int, modifier: Modifier = Modifier ) { - val iconTint = iconTintDark + val iconTint by remember { mutableStateOf(iconTintDark) } Card( shape = RectangleShape, colors = CardDefaults.cardColors( @@ -61,8 +55,7 @@ fun BottomAppBar( ), modifier = modifier .fillMaxWidth() - .navigationBarsPadding() - .height(80.dp) + .height(88.dp) ) { Row( @@ -70,6 +63,7 @@ fun BottomAppBar( horizontalArrangement = Arrangement.SpaceEvenly, modifier = modifier .fillMaxSize() + .navigationBarsPadding() ) { Icon( imageVector =Icons.Default.Key , @@ -124,12 +118,20 @@ fun BottomAppBar( @Preview( name = "BottomAppBar Preview Light", -// uiMode = Configuration.UI_MODE_NIGHT_NO, - showBackground = true + uiMode = Configuration.UI_MODE_NIGHT_YES, + showBackground = true, + showSystemUi = true ) @Composable -private fun p1() { +private fun P1() { HashinTheme(darkTheme = true, dynamicColor = false) { - BottomAppBar({}, {}, {}, 2) + Column( + verticalArrangement = Arrangement.Bottom, + modifier = Modifier + .fillMaxSize() + .background(MaterialTheme.colorScheme.background) + ) { + NavigationBar({}, {}, {}, 2) + } } } \ No newline at end of file diff --git a/app/src/main/java/com/karan/hashin/screens/home/Home.kt b/app/src/main/java/com/karan/hashin/screens/home/Home.kt index d054293..33bd2d3 100644 --- a/app/src/main/java/com/karan/hashin/screens/home/Home.kt +++ b/app/src/main/java/com/karan/hashin/screens/home/Home.kt @@ -8,7 +8,6 @@ import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview @@ -19,7 +18,7 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import androidx.navigation.navArgument -import com.karan.hashin.components.BottomAppBar +import com.karan.hashin.components.NavigationBar import com.karan.hashin.navigation.Screens import com.karan.hashin.ui.theme.HashinTheme import com.karan.hashin.viewmodel.HomeViewModel @@ -36,7 +35,7 @@ fun HomeScreen( Scaffold( bottomBar = { - BottomAppBar( + NavigationBar( toVault = { selection = 1 innerNav.navigate(Screens.HomeGraph.Vault.route) { @@ -70,9 +69,8 @@ fun HomeScreen( modifier = Modifier ) }, - modifier = Modifier - .navigationBarsPadding() - .statusBarsPadding() +// modifier = Modifier +// .navigationBarsPadding() ) { pd -> NavHost( navController = innerNav, diff --git a/app/src/main/java/com/karan/hashin/screens/home/Vault.kt b/app/src/main/java/com/karan/hashin/screens/home/Vault.kt index 1cc2ab9..00cef58 100644 --- a/app/src/main/java/com/karan/hashin/screens/home/Vault.kt +++ b/app/src/main/java/com/karan/hashin/screens/home/Vault.kt @@ -3,6 +3,7 @@ package com.karan.hashin.screens.home import android.util.Log import androidx.activity.compose.BackHandler import androidx.activity.compose.LocalOnBackPressedDispatcherOwner +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize @@ -12,6 +13,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf @@ -48,15 +50,10 @@ fun Vault( Column( modifier = modifier .fillMaxSize() + .background(MaterialTheme.colorScheme.background) .statusBarsPadding() .navigationBarsPadding() ) { - // Top App Bar -// TopAppBar( -// onSearch = { -// // TODO: Implement search functionality -// } -// ) // Content Box( @@ -73,7 +70,7 @@ fun Vault( } } else { val data = viewModel.passkeys.also { - Log.d("#ined", "data: ${it.toList()}") +// Log.d("#ined", "data: ${it.toList()}") } if (data.isEmpty()) { diff --git a/app/src/main/java/com/karan/hashin/ui/theme/Theme.kt b/app/src/main/java/com/karan/hashin/ui/theme/Theme.kt index 2eaa3cc..9a86196 100644 --- a/app/src/main/java/com/karan/hashin/ui/theme/Theme.kt +++ b/app/src/main/java/com/karan/hashin/ui/theme/Theme.kt @@ -18,10 +18,13 @@ import androidx.compose.ui.platform.LocalContext private val DarkColorScheme = darkColorScheme( + // Background + background = Color(0xFF121212), + // Primary Scheme primary = Color.White, // Icon color - primaryContainer = Color.Black, - onPrimaryContainer = Color.White, + primaryContainer = Color.Black , +// onPrimaryContainer = Color(0xFFEADDFF), // Secondary Scheme secondary = Color(0xFF9C27B0), @@ -38,10 +41,13 @@ private val DarkColorScheme = darkColorScheme( private val LightColorScheme = lightColorScheme( + // BackGround + background = Color(0xFFFFFBFE), + // Primary Scheme primary = Color.Black, - primaryContainer = Color.White, - onPrimaryContainer = Color.Black, + primaryContainer = Color(0xFFEADDFF), +// onPrimaryContainer = Color(0xFF21005D), // Secondary Scheme secondary = Color(0xFF9C27B0), From 03bd3803c9236a0900211a8a17b0aa34476ef701 Mon Sep 17 00:00:00 2001 From: Karan Joshi Date: Wed, 16 Jul 2025 23:35:24 +0530 Subject: [PATCH 02/10] dynamic Navigation bar --- .../java/com/karan/hashin/MainActivity.kt | 31 ++++++++++++++++++- .../karan/hashin/components/NavigationBar.kt | 14 +++++++-- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/karan/hashin/MainActivity.kt b/app/src/main/java/com/karan/hashin/MainActivity.kt index 38db257..fceb05c 100644 --- a/app/src/main/java/com/karan/hashin/MainActivity.kt +++ b/app/src/main/java/com/karan/hashin/MainActivity.kt @@ -1,9 +1,27 @@ package com.karan.hashin +import android.app.Activity +import android.graphics.Color.TRANSPARENT +import android.os.Build import android.os.Bundle +import android.view.View +import android.view.Window +import android.view.WindowInsets +import android.view.WindowInsetsController +import android.view.WindowManager import androidx.activity.ComponentActivity +import androidx.activity.SystemBarStyle import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge +import androidx.annotation.RequiresApi +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.SideEffect +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalView +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsControllerCompat import androidx.navigation.NavHostController import androidx.navigation.compose.rememberNavController import com.karan.hashin.navigation.NavGraph @@ -13,9 +31,20 @@ class MainActivity : ComponentActivity() { private lateinit var navController: NavHostController + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - enableEdgeToEdge() + + WindowCompat.setDecorFitsSystemWindows(window, false) + val lightTransparentStyle = SystemBarStyle.light( + scrim = TRANSPARENT, + darkScrim = TRANSPARENT + ) + + enableEdgeToEdge( + statusBarStyle = lightTransparentStyle, + navigationBarStyle = lightTransparentStyle + ) setContent { HashinTheme(dynamicColor = false) { diff --git a/app/src/main/java/com/karan/hashin/components/NavigationBar.kt b/app/src/main/java/com/karan/hashin/components/NavigationBar.kt index caae26d..3452cf3 100644 --- a/app/src/main/java/com/karan/hashin/components/NavigationBar.kt +++ b/app/src/main/java/com/karan/hashin/components/NavigationBar.kt @@ -10,11 +10,14 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Key @@ -55,15 +58,19 @@ fun NavigationBar( ), modifier = modifier .fillMaxWidth() - .height(88.dp) + .wrapContentHeight() +// .height(88.dp) ) { Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceEvenly, modifier = modifier - .fillMaxSize() - .navigationBarsPadding() + .fillMaxWidth() +// .navigationBarsPadding() + .padding(top = 8.dp) + .height(64.dp) + ) { Icon( imageVector =Icons.Default.Key , @@ -113,6 +120,7 @@ fun NavigationBar( } ) } + Spacer(Modifier.navigationBarsPadding()) } } From 56314a35834455f9ea39a5a4fbf4d6132fefcd48 Mon Sep 17 00:00:00 2001 From: Karan Joshi Date: Thu, 17 Jul 2025 01:04:19 +0530 Subject: [PATCH 03/10] home/passkey theming in progress... --- .../java/com/karan/hashin/MainActivity.kt | 11 +---- .../karan/hashin/components/NavigationBar.kt | 5 +-- .../com/karan/hashin/screens/home/PassKey.kt | 30 ++++++------- .../java/com/karan/hashin/ui/theme/Color.kt | 3 ++ .../java/com/karan/hashin/ui/theme/Theme.kt | 43 +++++++++++++------ 5 files changed, 52 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/com/karan/hashin/MainActivity.kt b/app/src/main/java/com/karan/hashin/MainActivity.kt index fceb05c..c7c6f01 100644 --- a/app/src/main/java/com/karan/hashin/MainActivity.kt +++ b/app/src/main/java/com/karan/hashin/MainActivity.kt @@ -11,6 +11,7 @@ import android.view.WindowInsetsController import android.view.WindowManager import androidx.activity.ComponentActivity import androidx.activity.SystemBarStyle +import androidx.activity.compose.LocalActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.annotation.RequiresApi @@ -36,15 +37,7 @@ class MainActivity : ComponentActivity() { super.onCreate(savedInstanceState) WindowCompat.setDecorFitsSystemWindows(window, false) - val lightTransparentStyle = SystemBarStyle.light( - scrim = TRANSPARENT, - darkScrim = TRANSPARENT - ) - - enableEdgeToEdge( - statusBarStyle = lightTransparentStyle, - navigationBarStyle = lightTransparentStyle - ) + setContent { HashinTheme(dynamicColor = false) { diff --git a/app/src/main/java/com/karan/hashin/components/NavigationBar.kt b/app/src/main/java/com/karan/hashin/components/NavigationBar.kt index 3452cf3..4dfc5d9 100644 --- a/app/src/main/java/com/karan/hashin/components/NavigationBar.kt +++ b/app/src/main/java/com/karan/hashin/components/NavigationBar.kt @@ -51,7 +51,7 @@ fun NavigationBar( Card( shape = RectangleShape, colors = CardDefaults.cardColors( - containerColor = MaterialTheme.colorScheme.primaryContainer + containerColor = MaterialTheme.colorScheme.tertiaryContainer ), elevation = CardDefaults.cardElevation( defaultElevation = 4.dp @@ -59,7 +59,6 @@ fun NavigationBar( modifier = modifier .fillMaxWidth() .wrapContentHeight() -// .height(88.dp) ) { Row( @@ -67,7 +66,6 @@ fun NavigationBar( horizontalArrangement = Arrangement.SpaceEvenly, modifier = modifier .fillMaxWidth() -// .navigationBarsPadding() .padding(top = 8.dp) .height(64.dp) @@ -93,7 +91,6 @@ fun NavigationBar( color = if(selection == 2) iconTint else MaterialTheme.colorScheme.primary, shape = RoundedCornerShape(percent = 33) ) -// ) { Icon( imageVector = Icons.Rounded.Add, diff --git a/app/src/main/java/com/karan/hashin/screens/home/PassKey.kt b/app/src/main/java/com/karan/hashin/screens/home/PassKey.kt index 9828c47..035f9ae 100644 --- a/app/src/main/java/com/karan/hashin/screens/home/PassKey.kt +++ b/app/src/main/java/com/karan/hashin/screens/home/PassKey.kt @@ -22,6 +22,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.scale import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.TextStyle @@ -31,10 +32,10 @@ import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.karan.hashin.R +import com.karan.hashin.ui.theme.BlueSelectionLight import com.karan.hashin.viewmodel.HomeViewModel import kotlinx.coroutines.launch -@OptIn(ExperimentalMaterial3Api::class) @Composable fun Passkey( viewModel: HomeViewModel, @@ -70,28 +71,26 @@ fun Passkey( verticalArrangement = Arrangement.spacedBy(16.dp), modifier = modifier .fillMaxSize() - .background(Color(0xFFF5F5F5)) + .background(MaterialTheme.colorScheme.background) .padding(16.dp) ) { Text( text = "${if (doEdit) "Update" else "Add"} Passkey ", style = MaterialTheme.typography.headlineMedium, - fontWeight = FontWeight.Bold, - color = Color(0xFF1A1A1A) + fontWeight = FontWeight.Bold ) Text( text = "${if (doEdit) "Update" else "Store"} your credentials securely", style = MaterialTheme.typography.bodyMedium, - color = Color.Gray ) Spacer(modifier = Modifier.height(16.dp)) Card( colors = CardDefaults.cardColors( - containerColor = Color.White, + containerColor = MaterialTheme.colorScheme.primaryContainer, ), elevation = CardDefaults.cardElevation( defaultElevation = 2.dp @@ -118,12 +117,12 @@ fun Passkey( } ?: false }, label = { Text("Service") }, - placeholder = { Text("eg. Github", color = Color.Black.copy(alpha = 0.4f)) }, + placeholder = { Text("eg. Github", color = MaterialTheme.colorScheme.primary.copy(alpha = 0.4f)) }, leadingIcon = { Icon(Icons.Default.Web, contentDescription = "Website name") }, modifier = Modifier.fillMaxWidth(), colors = OutlinedTextFieldDefaults.colors( - focusedBorderColor = Color(0xFF6200EE), - focusedLabelColor = Color(0xFF6200EE) + focusedBorderColor = MaterialTheme.colorScheme.outline, + focusedLabelColor = MaterialTheme.colorScheme.primary ) ) OutlinedTextField( @@ -143,8 +142,8 @@ fun Passkey( leadingIcon = { Icon(Icons.Default.Person, contentDescription = "Username") }, modifier = Modifier.fillMaxWidth(), colors = OutlinedTextFieldDefaults.colors( - focusedBorderColor = Color(0xFF6200EE), - focusedLabelColor = Color(0xFF6200EE) + focusedBorderColor = MaterialTheme.colorScheme.outline, + focusedLabelColor = MaterialTheme.colorScheme.primary ) ) @@ -170,8 +169,8 @@ fun Passkey( visualTransformation = if (isPasswordVisible) VisualTransformation.None else PasswordVisualTransformation(), modifier = Modifier.fillMaxWidth(), colors = OutlinedTextFieldDefaults.colors( - focusedBorderColor = Color(0xFF6200EE), - focusedLabelColor = Color(0xFF6200EE) + focusedBorderColor = MaterialTheme.colorScheme.outline, + focusedLabelColor = MaterialTheme.colorScheme.primary ) ) } @@ -179,7 +178,7 @@ fun Passkey( Card( colors = CardDefaults.cardColors( - containerColor = Color.White + containerColor = MaterialTheme.colorScheme.primaryContainer ), elevation = CardDefaults.cardElevation( defaultElevation = 2.dp @@ -211,7 +210,7 @@ fun Passkey( Text( text = "Add a description...", style = TextStyle( - color = Color.Gray, + color = MaterialTheme.colorScheme.primary, fontSize = 16.sp ) ) @@ -219,6 +218,7 @@ fun Passkey( innerTextField() } }, + cursorBrush = SolidColor(MaterialTheme.colorScheme.primary), modifier = Modifier.fillMaxSize() ) } diff --git a/app/src/main/java/com/karan/hashin/ui/theme/Color.kt b/app/src/main/java/com/karan/hashin/ui/theme/Color.kt index f60b0ce..5912dab 100644 --- a/app/src/main/java/com/karan/hashin/ui/theme/Color.kt +++ b/app/src/main/java/com/karan/hashin/ui/theme/Color.kt @@ -7,6 +7,9 @@ val iconTintLight = Color(0xFF2962FF) val iconTintDark = Color(0xFF82B1FF) val PurpleA700 = Color(0xFF9C27B0) +val BlueSelectionLight = Color(0xFF6200EE) +val BlueSelectionDark = Color(0xFF82B1FF) + val PurpleGrey80 = Color(0xFFCCC2DC) val Pink80 = Color(0xFFEFB8C8) diff --git a/app/src/main/java/com/karan/hashin/ui/theme/Theme.kt b/app/src/main/java/com/karan/hashin/ui/theme/Theme.kt index 9a86196..1dc84cb 100644 --- a/app/src/main/java/com/karan/hashin/ui/theme/Theme.kt +++ b/app/src/main/java/com/karan/hashin/ui/theme/Theme.kt @@ -1,7 +1,11 @@ package com.karan.hashin.ui.theme -import android.app.Activity +import android.graphics.Color.TRANSPARENT import android.os.Build +import androidx.activity.ComponentActivity +import androidx.activity.SystemBarStyle +import androidx.activity.compose.LocalActivity +import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material.ripple.LocalRippleTheme import androidx.compose.material.ripple.RippleAlpha @@ -13,6 +17,7 @@ import androidx.compose.material3.dynamicLightColorScheme import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.DisposableEffect import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext @@ -23,7 +28,7 @@ private val DarkColorScheme = darkColorScheme( // Primary Scheme primary = Color.White, // Icon color - primaryContainer = Color.Black , + primaryContainer = Color(0xFF292929) , // onPrimaryContainer = Color(0xFFEADDFF), // Secondary Scheme @@ -35,8 +40,10 @@ private val DarkColorScheme = darkColorScheme( // Tertiary Scheme tertiary = Color(0xFFF0F0F0), onTertiary = Color(0xFF666666), - tertiaryContainer = Color(0xFF4A4458), + tertiaryContainer = Color.Black, onTertiaryContainer = Color.White, + + outline = BlueSelectionDark ) private val LightColorScheme = lightColorScheme( @@ -57,16 +64,9 @@ private val LightColorScheme = lightColorScheme( // Tertiary Scheme tertiary = Color(0xFFF0F0F0), onTertiary = Color(0xFF666666), + tertiaryContainer = Color.White, - /* Other default colors to override - background = Color(0xFFFFFBFE), - surface = Color(0xFFFFFBFE), - onPrimary = Color.White, - onSecondary = Color.White, - onTertiary = Color.White, - onBackground = Color(0xFF1C1B1F), - onSurface = Color(0xFF1C1B1F), - */ + outline = BlueSelectionLight ) object NoRippleTheme : RippleTheme { @@ -81,6 +81,7 @@ fun HashinTheme( dynamicColor: Boolean = true, content: @Composable () -> Unit ) { + val activity = LocalActivity.current as ComponentActivity val colorScheme = when { dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { val context = LocalContext.current @@ -92,6 +93,24 @@ fun HashinTheme( } + DisposableEffect(darkTheme) { + val barStyle = if (darkTheme) { + SystemBarStyle.dark( + scrim = TRANSPARENT + ) + } else { + SystemBarStyle.light( + scrim = TRANSPARENT, + darkScrim = TRANSPARENT + ) + } + activity.enableEdgeToEdge( + statusBarStyle = barStyle, + navigationBarStyle = barStyle + ) + onDispose { } + } + MaterialTheme( colorScheme = colorScheme, typography = Typography, From 7d5072b21597391afe70ccf1fa2a87ce9b8e0410 Mon Sep 17 00:00:00 2001 From: Karan Joshi Date: Thu, 17 Jul 2025 23:56:31 +0530 Subject: [PATCH 04/10] home/PasskeyDetail theming --- .../com/karan/hashin/screens/home/PassKey.kt | 21 +++++++++++++++---- .../hashin/screens/home/PassKeyDetail.kt | 20 +++++++++++------- .../java/com/karan/hashin/ui/theme/Color.kt | 1 + 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/karan/hashin/screens/home/PassKey.kt b/app/src/main/java/com/karan/hashin/screens/home/PassKey.kt index 035f9ae..31cfdb1 100644 --- a/app/src/main/java/com/karan/hashin/screens/home/PassKey.kt +++ b/app/src/main/java/com/karan/hashin/screens/home/PassKey.kt @@ -32,7 +32,7 @@ import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.karan.hashin.R -import com.karan.hashin.ui.theme.BlueSelectionLight +import com.karan.hashin.ui.theme.Unfocused import com.karan.hashin.viewmodel.HomeViewModel import kotlinx.coroutines.launch @@ -121,6 +121,9 @@ fun Passkey( leadingIcon = { Icon(Icons.Default.Web, contentDescription = "Website name") }, modifier = Modifier.fillMaxWidth(), colors = OutlinedTextFieldDefaults.colors( + unfocusedBorderColor = Unfocused, + unfocusedLeadingIconColor = Unfocused, + focusedLeadingIconColor = MaterialTheme.colorScheme.primary, focusedBorderColor = MaterialTheme.colorScheme.outline, focusedLabelColor = MaterialTheme.colorScheme.primary ) @@ -142,6 +145,9 @@ fun Passkey( leadingIcon = { Icon(Icons.Default.Person, contentDescription = "Username") }, modifier = Modifier.fillMaxWidth(), colors = OutlinedTextFieldDefaults.colors( + unfocusedBorderColor = Unfocused, + unfocusedLeadingIconColor = Unfocused, + focusedLeadingIconColor = MaterialTheme.colorScheme.primary, focusedBorderColor = MaterialTheme.colorScheme.outline, focusedLabelColor = MaterialTheme.colorScheme.primary ) @@ -169,6 +175,9 @@ fun Passkey( visualTransformation = if (isPasswordVisible) VisualTransformation.None else PasswordVisualTransformation(), modifier = Modifier.fillMaxWidth(), colors = OutlinedTextFieldDefaults.colors( + unfocusedBorderColor = Unfocused, + unfocusedLeadingIconColor = Unfocused, + focusedLeadingIconColor = MaterialTheme.colorScheme.primary, focusedBorderColor = MaterialTheme.colorScheme.outline, focusedLabelColor = MaterialTheme.colorScheme.primary ) @@ -200,17 +209,22 @@ fun Passkey( ) } ?: false }, + textStyle = TextStyle( + color = MaterialTheme.colorScheme.primary, + fontSize = 16.sp + ), + cursorBrush = SolidColor(MaterialTheme.colorScheme.primary), decorationBox = { innerTextField -> Box( modifier = Modifier .fillMaxSize() - .padding(16.dp) + .padding(vertical = 16.dp, horizontal = 20.dp) ) { if (desc.isEmpty()) { Text( text = "Add a description...", style = TextStyle( - color = MaterialTheme.colorScheme.primary, + color = Unfocused, fontSize = 16.sp ) ) @@ -218,7 +232,6 @@ fun Passkey( innerTextField() } }, - cursorBrush = SolidColor(MaterialTheme.colorScheme.primary), modifier = Modifier.fillMaxSize() ) } diff --git a/app/src/main/java/com/karan/hashin/screens/home/PassKeyDetail.kt b/app/src/main/java/com/karan/hashin/screens/home/PassKeyDetail.kt index b9f285f..07152c1 100644 --- a/app/src/main/java/com/karan/hashin/screens/home/PassKeyDetail.kt +++ b/app/src/main/java/com/karan/hashin/screens/home/PassKeyDetail.kt @@ -109,7 +109,7 @@ fun PassKeyDetail( Column( modifier = modifier .fillMaxSize() - .background(Color(0xFFF8F9FA)) + .background(MaterialTheme.colorScheme.background) .verticalScroll(rememberScrollState()) ) { Row( @@ -132,7 +132,7 @@ fun PassKeyDetail( Icon( Icons.Default.ArrowBackIosNew, contentDescription = "Back", - tint = Color.Black + tint = MaterialTheme.colorScheme.primary ) } @@ -150,7 +150,7 @@ fun PassKeyDetail( Icon( Icons.Default.DeleteOutline, contentDescription = "Back", - tint = Color.Black + tint = MaterialTheme.colorScheme.primary ) } } @@ -159,12 +159,13 @@ fun PassKeyDetail( Column( modifier = Modifier .fillMaxWidth() - .padding(16.dp) + .padding(horizontal = 16.dp) + .padding(top = 32.dp) ) { // Header Card with Label Card( colors = CardDefaults.cardColors( - containerColor = Color(0xFF3F51B5) + containerColor = Color(0xFF3F51B5) // TODO(should be dynamic) ), elevation = CardDefaults.cardElevation( defaultElevation = 8.dp @@ -178,10 +179,13 @@ fun PassKeyDetail( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier .fillMaxWidth() - .padding(24.dp) + .padding(horizontal = 24.dp) + .padding(top = 16.dp, bottom = 24.dp) ) { Row( - horizontalArrangement = Arrangement.End + horizontalArrangement = Arrangement.End, + modifier = Modifier + .fillMaxWidth() ) { IconButton( onClick = { @@ -206,7 +210,7 @@ fun PassKeyDetail( modifier = Modifier .size(80.dp) .clip(CircleShape) - .background(Color.White.copy(alpha = 0.2f)) + .background(Color.White.copy(alpha = 0.1f)) ) { Text( text = passkey.label.firstOrNull()?.uppercase() ?: "", diff --git a/app/src/main/java/com/karan/hashin/ui/theme/Color.kt b/app/src/main/java/com/karan/hashin/ui/theme/Color.kt index 5912dab..06724a3 100644 --- a/app/src/main/java/com/karan/hashin/ui/theme/Color.kt +++ b/app/src/main/java/com/karan/hashin/ui/theme/Color.kt @@ -9,6 +9,7 @@ val iconTintDark = Color(0xFF82B1FF) val PurpleA700 = Color(0xFF9C27B0) val BlueSelectionLight = Color(0xFF6200EE) val BlueSelectionDark = Color(0xFF82B1FF) +val Unfocused = Color(red = 147, green = 143, blue = 153) val PurpleGrey80 = Color(0xFFCCC2DC) val Pink80 = Color(0xFFEFB8C8) From cce51a9da66a7da8f10cb4b44dcf033cb3a3e739 Mon Sep 17 00:00:00 2001 From: Karan Joshi Date: Fri, 18 Jul 2025 18:34:30 +0530 Subject: [PATCH 05/10] PasskeyDetail theming done --- .../com/karan/hashin/components/Element.kt | 2 +- .../com/karan/hashin/screens/home/Home.kt | 8 +-- .../com/karan/hashin/screens/home/PassKey.kt | 4 +- .../hashin/screens/home/PassKeyDetail.kt | 49 +++++++------------ .../java/com/karan/hashin/ui/theme/Color.kt | 5 ++ .../java/com/karan/hashin/ui/theme/Theme.kt | 31 +++++++++--- 6 files changed, 52 insertions(+), 47 deletions(-) diff --git a/app/src/main/java/com/karan/hashin/components/Element.kt b/app/src/main/java/com/karan/hashin/components/Element.kt index de91705..b0b5478 100644 --- a/app/src/main/java/com/karan/hashin/components/Element.kt +++ b/app/src/main/java/com/karan/hashin/components/Element.kt @@ -42,7 +42,7 @@ fun Element( Card( colors = CardDefaults.cardColors( - containerColor = MaterialTheme.colorScheme.primaryContainer + containerColor = MaterialTheme.colorScheme.surface ), elevation = CardDefaults.cardElevation( defaultElevation = 4.dp diff --git a/app/src/main/java/com/karan/hashin/screens/home/Home.kt b/app/src/main/java/com/karan/hashin/screens/home/Home.kt index 33bd2d3..e416dd5 100644 --- a/app/src/main/java/com/karan/hashin/screens/home/Home.kt +++ b/app/src/main/java/com/karan/hashin/screens/home/Home.kt @@ -2,13 +2,11 @@ package com.karan.hashin.screens.home import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue -import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.lifecycle.viewmodel.compose.viewModel @@ -31,7 +29,7 @@ fun HomeScreen( modifier: Modifier = Modifier ) { val innerNav = rememberNavController() - var selection by remember { mutableIntStateOf(1) } + var selection by rememberSaveable { mutableIntStateOf(1) } Scaffold( bottomBar = { @@ -69,8 +67,6 @@ fun HomeScreen( modifier = Modifier ) }, -// modifier = Modifier -// .navigationBarsPadding() ) { pd -> NavHost( navController = innerNav, diff --git a/app/src/main/java/com/karan/hashin/screens/home/PassKey.kt b/app/src/main/java/com/karan/hashin/screens/home/PassKey.kt index 31cfdb1..82fc628 100644 --- a/app/src/main/java/com/karan/hashin/screens/home/PassKey.kt +++ b/app/src/main/java/com/karan/hashin/screens/home/PassKey.kt @@ -90,7 +90,7 @@ fun Passkey( Card( colors = CardDefaults.cardColors( - containerColor = MaterialTheme.colorScheme.primaryContainer, + containerColor = MaterialTheme.colorScheme.surface, ), elevation = CardDefaults.cardElevation( defaultElevation = 2.dp @@ -187,7 +187,7 @@ fun Passkey( Card( colors = CardDefaults.cardColors( - containerColor = MaterialTheme.colorScheme.primaryContainer + containerColor = MaterialTheme.colorScheme.surface ), elevation = CardDefaults.cardElevation( defaultElevation = 2.dp diff --git a/app/src/main/java/com/karan/hashin/screens/home/PassKeyDetail.kt b/app/src/main/java/com/karan/hashin/screens/home/PassKeyDetail.kt index 07152c1..304a0b2 100644 --- a/app/src/main/java/com/karan/hashin/screens/home/PassKeyDetail.kt +++ b/app/src/main/java/com/karan/hashin/screens/home/PassKeyDetail.kt @@ -4,6 +4,7 @@ import android.content.ClipData import android.content.ClipboardManager import android.content.Context import android.graphics.drawable.Icon +import android.text.Layout import android.util.Log import android.widget.Toast import androidx.compose.animation.AnimatedVisibility @@ -116,7 +117,7 @@ fun PassKeyDetail( horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier .fillMaxWidth() - .padding(horizontal = 16.dp) + .padding(16.dp) ) { Box( modifier = Modifier @@ -159,13 +160,13 @@ fun PassKeyDetail( Column( modifier = Modifier .fillMaxWidth() - .padding(horizontal = 16.dp) - .padding(top = 32.dp) + .padding(16.dp) ) { // Header Card with Label Card( colors = CardDefaults.cardColors( containerColor = Color(0xFF3F51B5) // TODO(should be dynamic) + ), elevation = CardDefaults.cardElevation( defaultElevation = 8.dp @@ -247,7 +248,7 @@ fun PassKeyDetail( modifier = Modifier .fillMaxWidth(), colors = CardDefaults.cardColors( - containerColor = Color.White + containerColor = MaterialTheme.colorScheme.surface ), elevation = CardDefaults.cardElevation( defaultElevation = 4.dp @@ -353,7 +354,7 @@ private fun UsernameField( ) { Card( colors = CardDefaults.cardColors( - containerColor = Color(0xFFF8F9FA) + containerColor = MaterialTheme.colorScheme.surfaceVariant ), shape = RoundedCornerShape(12.dp), modifier = Modifier @@ -368,8 +369,8 @@ private fun UsernameField( Icon( imageVector = Icons.Default.Person, contentDescription = null, - tint = Color.Black, - modifier = Modifier.size(28.dp) + tint = MaterialTheme.colorScheme.primary, + modifier = Modifier.size(24.dp) ) Spacer(modifier = Modifier.width(12.dp)) @@ -391,7 +392,7 @@ private fun UsernameField( Icon( Icons.Default.ContentCopy, contentDescription = "Copy", - tint = Color.Black, + tint = MaterialTheme.colorScheme.primary, modifier = Modifier.size(18.dp) ) } @@ -407,11 +408,9 @@ private fun PasswordField( onValueChange: (String) -> Unit ) { - var pass by remember { mutableStateOf("") } - Card( colors = CardDefaults.cardColors( - containerColor = Color(0xFFF8F9FA) + containerColor = MaterialTheme.colorScheme.surfaceVariant ), shape = RoundedCornerShape(12.dp), modifier = Modifier @@ -426,12 +425,10 @@ private fun PasswordField( Icon( imageVector = Icons.Default.Lock, contentDescription = null, - tint = Color.Black, - modifier = Modifier.size(28.dp) + tint = MaterialTheme.colorScheme.primary, + modifier = Modifier.size(24.dp) ) - Spacer(modifier = Modifier.width(12.dp)) - Column( modifier = Modifier.weight(1f) ) { @@ -443,34 +440,24 @@ private fun PasswordField( readOnly = !isVisible, visualTransformation = if (isVisible) VisualTransformation.None else PasswordVisualTransformation(), colors = TextFieldDefaults.colors( - focusedContainerColor = Color(0xFFF8F9FA), - unfocusedContainerColor = Color(0xFFF8F9FA), - disabledContainerColor = Color(0xFFF8F9FA), unfocusedIndicatorColor = Color.Transparent, focusedIndicatorColor = Color.Transparent, disabledIndicatorColor = Color.Transparent - ) + ), ) } - // Visibility Toggle Button - Box( + // Visibility Button + IconButton( + onClick = onVisibilityToggle, modifier = Modifier .size(32.dp) - .semantics { role = Role.Button } - .clickable( - indication = null, - interactionSource = remember { MutableInteractionSource() } - ) { - onVisibilityToggle() - } ) { Icon( if (isVisible) Icons.Default.Visibility else Icons.Default.VisibilityOff, contentDescription = "Toggle visibility", - tint = Color.Black, - modifier = Modifier - .size(18.dp) + tint = MaterialTheme.colorScheme.primary, + modifier = Modifier.size(18.dp) ) } } diff --git a/app/src/main/java/com/karan/hashin/ui/theme/Color.kt b/app/src/main/java/com/karan/hashin/ui/theme/Color.kt index 06724a3..afbfc73 100644 --- a/app/src/main/java/com/karan/hashin/ui/theme/Color.kt +++ b/app/src/main/java/com/karan/hashin/ui/theme/Color.kt @@ -11,6 +11,11 @@ val BlueSelectionLight = Color(0xFF6200EE) val BlueSelectionDark = Color(0xFF82B1FF) val Unfocused = Color(red = 147, green = 143, blue = 153) +val SurfaceDark = Color(0xFF1E1E1E) +val SurfaceLight = Color.White +val SurfaceVariantDark = Color(0xFF2A2A2A) +val SurfaceVariantLight = Color(0xFFF2F2F2) + val PurpleGrey80 = Color(0xFFCCC2DC) val Pink80 = Color(0xFFEFB8C8) diff --git a/app/src/main/java/com/karan/hashin/ui/theme/Theme.kt b/app/src/main/java/com/karan/hashin/ui/theme/Theme.kt index 1dc84cb..877c025 100644 --- a/app/src/main/java/com/karan/hashin/ui/theme/Theme.kt +++ b/app/src/main/java/com/karan/hashin/ui/theme/Theme.kt @@ -28,13 +28,13 @@ private val DarkColorScheme = darkColorScheme( // Primary Scheme primary = Color.White, // Icon color - primaryContainer = Color(0xFF292929) , + primaryContainer = Color(0xFF292929), // onPrimaryContainer = Color(0xFFEADDFF), // Secondary Scheme secondary = Color(0xFF9C27B0), onSecondary = Color.White, - secondaryContainer = Color(0xFF41484D) , + secondaryContainer = Color(0xFF41484D), onSecondaryContainer = Color.White, // Tertiary Scheme @@ -43,7 +43,17 @@ private val DarkColorScheme = darkColorScheme( tertiaryContainer = Color.Black, onTertiaryContainer = Color.White, - outline = BlueSelectionDark + outline = BlueSelectionDark, + + // Surface + surface = SurfaceDark, + surfaceTint = SurfaceDark, + surfaceVariant = SurfaceVariantDark, + surfaceContainer = Color(0xFF242424), + onSurface = Color.White, + onSurfaceVariant = Color.White, +// surfaceContainerLow = Color(0xFF1B1B1B), +// surfaceContainerHigh = Color(0xFF2E2E2E) ) private val LightColorScheme = lightColorScheme( @@ -66,12 +76,19 @@ private val LightColorScheme = lightColorScheme( onTertiary = Color(0xFF666666), tertiaryContainer = Color.White, - outline = BlueSelectionLight + outline = BlueSelectionLight, + + surface = SurfaceLight, + surfaceVariant = SurfaceVariantLight, + surfaceContainer = Color(0xFFF7F7F7), + surfaceTint = SurfaceLight, ) object NoRippleTheme : RippleTheme { - @Composable override fun defaultColor() = Color.Unspecified - @Composable override fun rippleAlpha() = RippleAlpha(0f, 0f, 0f, 0f) + @Composable + override fun defaultColor() = Color.Unspecified + @Composable + override fun rippleAlpha() = RippleAlpha(0f, 0f, 0f, 0f) } @Composable @@ -115,7 +132,7 @@ fun HashinTheme( colorScheme = colorScheme, typography = Typography, - ) { + ) { CompositionLocalProvider( LocalRippleTheme provides NoRippleTheme, ) { From 2fa323c7f9718af8694683a62eed71453a77db38 Mon Sep 17 00:00:00 2001 From: Karan Joshi Date: Fri, 18 Jul 2025 23:46:49 +0530 Subject: [PATCH 06/10] home/setting theming done --- .../com/karan/hashin/screens/home/Home.kt | 2 +- .../com/karan/hashin/screens/home/PassKey.kt | 7 +- .../com/karan/hashin/screens/home/Settings.kt | 214 +++++++----------- .../java/com/karan/hashin/ui/theme/Color.kt | 7 +- .../java/com/karan/hashin/ui/theme/Theme.kt | 3 + 5 files changed, 96 insertions(+), 137 deletions(-) diff --git a/app/src/main/java/com/karan/hashin/screens/home/Home.kt b/app/src/main/java/com/karan/hashin/screens/home/Home.kt index e416dd5..e941aa3 100644 --- a/app/src/main/java/com/karan/hashin/screens/home/Home.kt +++ b/app/src/main/java/com/karan/hashin/screens/home/Home.kt @@ -96,7 +96,7 @@ fun HomeScreen( composable( route = Screens.HomeGraph.Setting.route ) { - Settings(viewModel) +// Settings(viewModel) } composable( diff --git a/app/src/main/java/com/karan/hashin/screens/home/PassKey.kt b/app/src/main/java/com/karan/hashin/screens/home/PassKey.kt index 82fc628..c639363 100644 --- a/app/src/main/java/com/karan/hashin/screens/home/PassKey.kt +++ b/app/src/main/java/com/karan/hashin/screens/home/PassKey.kt @@ -32,6 +32,9 @@ import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.karan.hashin.R +import com.karan.hashin.ui.theme.Blue +import com.karan.hashin.ui.theme.Gray +import com.karan.hashin.ui.theme.Purple import com.karan.hashin.ui.theme.Unfocused import com.karan.hashin.viewmodel.HomeViewModel import kotlinx.coroutines.launch @@ -291,7 +294,7 @@ fun Passkey( .fillMaxWidth() .height(56.dp), colors = ButtonDefaults.buttonColors( - containerColor = Color(0xFF6200EE) + containerColor = Blue ), shape = RoundedCornerShape(12.dp) ) { @@ -366,7 +369,7 @@ fun LabelSelector( } .scale(scale.value), colors = CardDefaults.cardColors( - containerColor = if (isSelected) Color(0xFF9C27B0) else Color(0xFFF0F0F0) + containerColor = if (isSelected) Purple else Gray ), elevation = CardDefaults.cardElevation( defaultElevation = elevation.value diff --git a/app/src/main/java/com/karan/hashin/screens/home/Settings.kt b/app/src/main/java/com/karan/hashin/screens/home/Settings.kt index 2439896..2b76022 100644 --- a/app/src/main/java/com/karan/hashin/screens/home/Settings.kt +++ b/app/src/main/java/com/karan/hashin/screens/home/Settings.kt @@ -1,129 +1,120 @@ package com.karan.hashin.screens.home +import android.content.res.Configuration +import androidx.compose.runtime.getValue +import androidx.compose.runtime.setValue import androidx.compose.animation.core.* import androidx.compose.foundation.background import androidx.compose.foundation.clickable +import androidx.compose.foundation.gestures.scrollable import androidx.compose.foundation.layout.* +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.* import androidx.compose.material3.* import androidx.compose.runtime.* +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.scale -import androidx.compose.ui.draw.shadow import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import androidx.lifecycle.viewmodel.compose.viewModel +import androidx.compose.ui.tooling.preview.Preview +import com.karan.hashin.ui.theme.Blue import com.karan.hashin.ui.theme.HashinTheme -import com.karan.hashin.viewmodel.HomeViewModel @Composable fun Settings( - viewModel: HomeViewModel, modifier: Modifier = Modifier ) { val context = LocalContext.current - var isDarkTheme by remember { mutableStateOf(false) } - - // Animation for profile section - val infiniteTransition = rememberInfiniteTransition(label = "profile") + var isDarkTheme by rememberSaveable { mutableStateOf(false) } + var scrollState = rememberScrollState(0) + + val infiniteTransition = rememberInfiniteTransition() val profileScale by infiniteTransition.animateFloat( initialValue = 1f, targetValue = 1.05f, animationSpec = infiniteRepeatable( animation = tween(2000), repeatMode = RepeatMode.Reverse - ), - label = "profile" + ) ) Column( + verticalArrangement = Arrangement.spacedBy(16.dp), modifier = modifier + .statusBarsPadding() + .padding(16.dp) .fillMaxSize() - .background( - brush = Brush.verticalGradient( - colors = listOf( - MaterialTheme.colorScheme.background, - MaterialTheme.colorScheme.background.copy(alpha = 0.95f) - ) - ) - ) - .padding(16.dp), - verticalArrangement = Arrangement.spacedBy(20.dp) + .background(MaterialTheme.colorScheme.background) + .verticalScroll(scrollState) ) { - // Profile Section with Animation - Card( - modifier = Modifier - .fillMaxWidth() - .shadow( - elevation = 8.dp, - shape = RoundedCornerShape(24.dp) - ), - colors = CardDefaults.cardColors( + // Profile Card + ElevatedCard( + elevation = CardDefaults.elevatedCardElevation(defaultElevation = 8.dp), + shape = RoundedCornerShape(24.dp), + colors = CardDefaults.elevatedCardColors( containerColor = MaterialTheme.colorScheme.surface ), - shape = RoundedCornerShape(24.dp) + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 8.dp) ) { Column( - modifier = Modifier.padding(24.dp), - horizontalAlignment = Alignment.CenterHorizontally + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier.padding(24.dp) ) { Box( + contentAlignment = Alignment.Center, modifier = Modifier .size(100.dp) .scale(profileScale) .clip(CircleShape) .background( - brush = Brush.linearGradient( + Brush.linearGradient( colors = listOf( MaterialTheme.colorScheme.primary, MaterialTheme.colorScheme.tertiary ) ) - ), - contentAlignment = Alignment.Center + ) ) { Icon( imageVector = Icons.Default.Person, contentDescription = "Profile", - modifier = Modifier.size(50.dp), - tint = Color.White + tint = Color.White, + modifier = Modifier.size(50.dp) ) } - Spacer(modifier = Modifier.height(20.dp)) - Text( text = "John Doe", style = MaterialTheme.typography.headlineMedium, fontWeight = FontWeight.Bold, color = MaterialTheme.colorScheme.onSurface ) - Text( text = "john.doe@example.com", style = MaterialTheme.typography.bodyLarge, color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f) ) - Spacer(modifier = Modifier.height(20.dp)) - Button( - onClick = { /* TODO: Handle edit profile */ }, + onClick = { /* Edit profile */ }, modifier = Modifier .fillMaxWidth() .height(50.dp), colors = ButtonDefaults.buttonColors( - containerColor = MaterialTheme.colorScheme.primary + containerColor = Blue ), shape = RoundedCornerShape(16.dp) ) { @@ -133,34 +124,27 @@ fun Settings( modifier = Modifier.size(24.dp) ) Spacer(modifier = Modifier.width(8.dp)) - Text( - "Edit Profile", - style = MaterialTheme.typography.titleMedium - ) + Text("Edit Profile", style = MaterialTheme.typography.titleMedium) } } } - // Settings Options with Modern Cards - Card( + // Settings Options Card + ElevatedCard( modifier = Modifier .fillMaxWidth() - .shadow( - elevation = 8.dp, - shape = RoundedCornerShape(24.dp) - ), - colors = CardDefaults.cardColors( + .padding(vertical = 8.dp), + elevation = CardDefaults.elevatedCardElevation(defaultElevation = 8.dp), + shape = RoundedCornerShape(24.dp), + colors = CardDefaults.elevatedCardColors( containerColor = MaterialTheme.colorScheme.surface - ), - shape = RoundedCornerShape(24.dp) + ) ) { - Column( - modifier = Modifier.padding(16.dp) - ) { + Column(modifier = Modifier.padding(16.dp)) { SettingsItem( icon = Icons.Default.DarkMode, title = "Dark Theme", - description = "Switch between light and dark mode", + description = "Switch to dark mode", trailing = { Switch( checked = isDarkTheme, @@ -174,66 +158,41 @@ fun Settings( ) } ) - - Divider( - modifier = Modifier.padding(horizontal = 16.dp), - color = MaterialTheme.colorScheme.outline.copy(alpha = 0.1f) - ) - + Divider(color = MaterialTheme.colorScheme.outline.copy(alpha = 0.1f)) SettingsItem( icon = Icons.Default.Notifications, title = "Notifications", - description = "Manage your notification preferences", - onClick = { /* TODO: Handle notifications */ } + description = "Manage notifications", + onClick = { } ) - - Divider( - modifier = Modifier.padding(horizontal = 16.dp), - color = MaterialTheme.colorScheme.outline.copy(alpha = 0.1f) - ) - + Divider(color = MaterialTheme.colorScheme.outline.copy(alpha = 0.1f)) SettingsItem( icon = Icons.Default.Security, title = "Security", - description = "Manage your security settings", - onClick = { /* TODO: Handle security */ } - ) - - Divider( - modifier = Modifier.padding(horizontal = 16.dp), - color = MaterialTheme.colorScheme.outline.copy(alpha = 0.1f) + description = "Manage security settings", + onClick = { } ) - + Divider(color = MaterialTheme.colorScheme.outline.copy(alpha = 0.1f)) SettingsItem( - icon = Icons.Default.Help, + icon = Icons.Default.Feedback, title = "Help & Support", - description = "Get help and contact support", - onClick = { /* TODO: Handle help */ } + description = "Get help & contact support", + onClick = { } ) } } - // Sign Out Button with Gradient Button( - onClick = { /* TODO: Handle sign out */ }, - modifier = Modifier - .fillMaxWidth() - .height(56.dp), + onClick = { /* Sign out */ }, colors = ButtonDefaults.buttonColors( containerColor = MaterialTheme.colorScheme.error ), - shape = RoundedCornerShape(16.dp) + shape = RoundedCornerShape(16.dp), + modifier = Modifier + .fillMaxWidth() + .height(56.dp) ) { - Icon( - imageVector = Icons.Default.Logout, - contentDescription = null, - modifier = Modifier.size(24.dp) - ) - Spacer(modifier = Modifier.width(8.dp)) - Text( - "Sign Out", - style = MaterialTheme.typography.titleMedium - ) + Text("Sign Out", style = MaterialTheme.typography.titleMedium) } } } @@ -255,52 +214,43 @@ private fun SettingsItem( verticalAlignment = Alignment.CenterVertically ) { Box( + contentAlignment = Alignment.Center, modifier = Modifier .size(40.dp) .clip(RoundedCornerShape(12.dp)) - .background(MaterialTheme.colorScheme.primary.copy(alpha = 0.1f)), - contentAlignment = Alignment.Center + .background(MaterialTheme.colorScheme.primary.copy(alpha = 0.1f)) ) { - Icon( - imageVector = icon, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier.size(24.dp) - ) + Icon(icon, contentDescription = null, tint = MaterialTheme.colorScheme.primary) } - Spacer(modifier = Modifier.width(16.dp)) - Column(modifier = Modifier.weight(1f)) { - Text( - text = title, - style = MaterialTheme.typography.titleMedium, - color = MaterialTheme.colorScheme.onSurface - ) - Text( - text = description, - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f) - ) + Text(title, style = MaterialTheme.typography.titleMedium, color = MaterialTheme.colorScheme.onSurface) + Text(description, style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)) } - if (trailing != null) { trailing() } else { Icon( - imageVector = Icons.Default.ChevronRight, + Icons.Default.ChevronRight, contentDescription = null, - tint = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f), - modifier = Modifier.size(24.dp) + tint = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f) ) } } } -@Preview +@Preview(showBackground = true, showSystemUi = true, uiMode = Configuration.UI_MODE_NIGHT_NO) @Composable -private fun PreviewSetting() { - HashinTheme { - Settings(viewModel()) +fun PreviewSettingsLight() { + MaterialTheme() { + Settings() } -} \ No newline at end of file +} + +//@Preview(showBackground = true, showSystemUi = true) +//@Composable +//fun PreviewSettingsDark() { +// MaterialTheme(colorScheme = darkColorScheme()) { +// Settings() +// } +//} diff --git a/app/src/main/java/com/karan/hashin/ui/theme/Color.kt b/app/src/main/java/com/karan/hashin/ui/theme/Color.kt index afbfc73..482715f 100644 --- a/app/src/main/java/com/karan/hashin/ui/theme/Color.kt +++ b/app/src/main/java/com/karan/hashin/ui/theme/Color.kt @@ -6,7 +6,10 @@ import androidx.compose.ui.graphics.Color val iconTintLight = Color(0xFF2962FF) val iconTintDark = Color(0xFF82B1FF) -val PurpleA700 = Color(0xFF9C27B0) +val Purple = Color(0xFF9C27B0) +val Blue = Color(0xFF6200EE) +val Gray = Color(0xFFF0F0F0) + val BlueSelectionLight = Color(0xFF6200EE) val BlueSelectionDark = Color(0xFF82B1FF) val Unfocused = Color(red = 147, green = 143, blue = 153) @@ -19,6 +22,6 @@ val SurfaceVariantLight = Color(0xFFF2F2F2) val PurpleGrey80 = Color(0xFFCCC2DC) val Pink80 = Color(0xFFEFB8C8) -val Purple40 = Color(0xFF6650a4) +val Purple40 = Color(0xFF6650A4) val PurpleGrey40 = Color(0xFF625b71) val Pink40 = Color(0xFF7D5260) \ No newline at end of file diff --git a/app/src/main/java/com/karan/hashin/ui/theme/Theme.kt b/app/src/main/java/com/karan/hashin/ui/theme/Theme.kt index 877c025..6ff4869 100644 --- a/app/src/main/java/com/karan/hashin/ui/theme/Theme.kt +++ b/app/src/main/java/com/karan/hashin/ui/theme/Theme.kt @@ -82,6 +82,9 @@ private val LightColorScheme = lightColorScheme( surfaceVariant = SurfaceVariantLight, surfaceContainer = Color(0xFFF7F7F7), surfaceTint = SurfaceLight, + onSurface = Color.Black, + onSurfaceVariant = Color.Black, + ) object NoRippleTheme : RippleTheme { From 57a76a6788d5f0cc4c5122febb7399d71b737b24 Mon Sep 17 00:00:00 2001 From: Karan Joshi Date: Sat, 19 Jul 2025 22:28:54 +0530 Subject: [PATCH 07/10] EditProfile screen processing... --- .../karan/hashin/screens/home/EditProfile.kt | 154 ++++++++++++++++++ .../com/karan/hashin/screens/home/Home.kt | 2 +- .../com/karan/hashin/screens/home/Settings.kt | 45 ++--- .../java/com/karan/hashin/ui/theme/Theme.kt | 4 + 4 files changed, 176 insertions(+), 29 deletions(-) create mode 100644 app/src/main/java/com/karan/hashin/screens/home/EditProfile.kt diff --git a/app/src/main/java/com/karan/hashin/screens/home/EditProfile.kt b/app/src/main/java/com/karan/hashin/screens/home/EditProfile.kt new file mode 100644 index 0000000..8be94cf --- /dev/null +++ b/app/src/main/java/com/karan/hashin/screens/home/EditProfile.kt @@ -0,0 +1,154 @@ +package com.karan.hashin.screens.home + +import com.karan.hashin.R +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.* +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.AccountCircle +import androidx.compose.material.icons.filled.Edit +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.shadow +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview +import com.karan.hashin.ui.theme.HashinTheme + +@Composable +fun EditProfileScreen() { + var name by remember { mutableStateOf("") } + var email by remember { mutableStateOf("") } + + // Professional, neutral background + Box( + modifier = Modifier + .fillMaxSize() + .background(Color(0xFFF7F7F7)) + ) { + Column( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 24.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + Card( + modifier = Modifier + .fillMaxWidth() + .wrapContentHeight() + .shadow(6.dp, RoundedCornerShape(20.dp)), + shape = RoundedCornerShape(20.dp), + colors = CardDefaults.cardColors(containerColor = Color.White), + elevation = CardDefaults.cardElevation(4.dp), + border = BorderStroke(1.dp, Color(0xFFE0E0E0)) + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 24.dp, vertical = 32.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + // Simple avatar + Box( + modifier = Modifier + .size(90.dp) + .clip(CircleShape) + .background(Color(0xFFE0E0E0)), + contentAlignment = Alignment.Center + ) { + Icon( + imageVector = Icons.Default.AccountCircle, + contentDescription = "Profile Picture", + tint = Color(0xFFB0B0B0), + modifier = Modifier.size(80.dp) + ) + } + Spacer(modifier = Modifier.height(18.dp)) + Text( + text = "Edit Profile", + fontSize = 22.sp, + fontWeight = FontWeight.SemiBold, + color = Color(0xFF22223B), + modifier = Modifier.padding(bottom = 18.dp) + ) + // Name Field + OutlinedTextField( + value = name, + onValueChange = { name = it }, + label = { Text("Name") }, + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 4.dp), + shape = RoundedCornerShape(12.dp), + colors = OutlinedTextFieldDefaults.colors( + focusedBorderColor = Color(0xFF22223B), + unfocusedBorderColor = Color(0xFFE0E0E0), + cursorColor = Color(0xFF22223B) + ) + ) + // Email Field + OutlinedTextField( + value = email, + onValueChange = { email = it }, + label = { Text("Email") }, + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 4.dp), + shape = RoundedCornerShape(12.dp), + colors = OutlinedTextFieldDefaults.colors( + focusedBorderColor = Color(0xFF22223B), + unfocusedBorderColor = Color(0xFFE0E0E0), + cursorColor = Color(0xFF22223B) + ) + ) + Spacer(modifier = Modifier.height(22.dp)) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(12.dp) + ) { + Button( + onClick = { /* Save action */ }, + modifier = Modifier.weight(1f), + shape = RoundedCornerShape(12.dp), + colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF22223B)) + ) { + Text("Save", color = Color.White, fontWeight = FontWeight.Medium) + } + OutlinedButton( + onClick = { /* Cancel action */ }, + modifier = Modifier.weight(1f), + shape = RoundedCornerShape(12.dp), + border = BorderStroke(1.5.dp, Color(0xFF22223B)), + colors = ButtonDefaults.outlinedButtonColors(contentColor = Color(0xFF22223B)) + ) { + Text("Cancel", fontWeight = FontWeight.Medium) + } + } + } + } + } + } +} + +@Preview(showBackground = true) +@Composable +fun EditProfileScreenPreview() { + MaterialTheme { + EditProfileScreen() + } +} + diff --git a/app/src/main/java/com/karan/hashin/screens/home/Home.kt b/app/src/main/java/com/karan/hashin/screens/home/Home.kt index e941aa3..e416dd5 100644 --- a/app/src/main/java/com/karan/hashin/screens/home/Home.kt +++ b/app/src/main/java/com/karan/hashin/screens/home/Home.kt @@ -96,7 +96,7 @@ fun HomeScreen( composable( route = Screens.HomeGraph.Setting.route ) { -// Settings(viewModel) + Settings(viewModel) } composable( diff --git a/app/src/main/java/com/karan/hashin/screens/home/Settings.kt b/app/src/main/java/com/karan/hashin/screens/home/Settings.kt index 2b76022..4b4f0f4 100644 --- a/app/src/main/java/com/karan/hashin/screens/home/Settings.kt +++ b/app/src/main/java/com/karan/hashin/screens/home/Settings.kt @@ -28,33 +28,26 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.tooling.preview.Preview +import androidx.lifecycle.viewmodel.compose.viewModel import com.karan.hashin.ui.theme.Blue import com.karan.hashin.ui.theme.HashinTheme +import com.karan.hashin.viewmodel.HomeViewModel @Composable fun Settings( + viewModel: HomeViewModel, modifier: Modifier = Modifier ) { val context = LocalContext.current var isDarkTheme by rememberSaveable { mutableStateOf(false) } var scrollState = rememberScrollState(0) - val infiniteTransition = rememberInfiniteTransition() - val profileScale by infiniteTransition.animateFloat( - initialValue = 1f, - targetValue = 1.05f, - animationSpec = infiniteRepeatable( - animation = tween(2000), - repeatMode = RepeatMode.Reverse - ) - ) - Column( - verticalArrangement = Arrangement.spacedBy(16.dp), + verticalArrangement = Arrangement.spacedBy(8.dp), modifier = modifier .statusBarsPadding() - .padding(16.dp) .fillMaxSize() + .padding(horizontal = 16.dp) .background(MaterialTheme.colorScheme.background) .verticalScroll(scrollState) ) { @@ -77,16 +70,8 @@ fun Settings( contentAlignment = Alignment.Center, modifier = Modifier .size(100.dp) - .scale(profileScale) .clip(CircleShape) - .background( - Brush.linearGradient( - colors = listOf( - MaterialTheme.colorScheme.primary, - MaterialTheme.colorScheme.tertiary - ) - ) - ) + .background(MaterialTheme.colorScheme.tertiary) ) { Icon( imageVector = Icons.Default.Person, @@ -121,10 +106,11 @@ fun Settings( Icon( imageVector = Icons.Default.Edit, contentDescription = null, + tint = Color.White, modifier = Modifier.size(24.dp) ) Spacer(modifier = Modifier.width(8.dp)) - Text("Edit Profile", style = MaterialTheme.typography.titleMedium) + Text("Edit Profile", style = MaterialTheme.typography.titleMedium, color = Color.White) } } } @@ -150,10 +136,12 @@ fun Settings( checked = isDarkTheme, onCheckedChange = { isDarkTheme = it }, colors = SwitchDefaults.colors( - checkedThumbColor = MaterialTheme.colorScheme.primary, - checkedTrackColor = MaterialTheme.colorScheme.primaryContainer, - uncheckedThumbColor = MaterialTheme.colorScheme.outline, - uncheckedTrackColor = MaterialTheme.colorScheme.surfaceVariant + uncheckedThumbColor = MaterialTheme.colorScheme.primary, + uncheckedTrackColor = MaterialTheme.colorScheme.surface, + uncheckedBorderColor = MaterialTheme.colorScheme.surfaceVariant, + checkedThumbColor = MaterialTheme.colorScheme.outline, + checkedTrackColor = MaterialTheme.colorScheme.surface, + checkedBorderColor = MaterialTheme.colorScheme.outline ) ) } @@ -190,9 +178,10 @@ fun Settings( shape = RoundedCornerShape(16.dp), modifier = Modifier .fillMaxWidth() + .padding(bottom = 32.dp) .height(56.dp) ) { - Text("Sign Out", style = MaterialTheme.typography.titleMedium) + Text("Sign Out", style = MaterialTheme.typography.titleMedium, color = Color.White) } } } @@ -243,7 +232,7 @@ private fun SettingsItem( @Composable fun PreviewSettingsLight() { MaterialTheme() { - Settings() + Settings(viewModel()) } } diff --git a/app/src/main/java/com/karan/hashin/ui/theme/Theme.kt b/app/src/main/java/com/karan/hashin/ui/theme/Theme.kt index 6ff4869..ddfdaeb 100644 --- a/app/src/main/java/com/karan/hashin/ui/theme/Theme.kt +++ b/app/src/main/java/com/karan/hashin/ui/theme/Theme.kt @@ -54,6 +54,8 @@ private val DarkColorScheme = darkColorScheme( onSurfaceVariant = Color.White, // surfaceContainerLow = Color(0xFF1B1B1B), // surfaceContainerHigh = Color(0xFF2E2E2E) + + error = Color(0xFFCF6679), ) private val LightColorScheme = lightColorScheme( @@ -85,6 +87,8 @@ private val LightColorScheme = lightColorScheme( onSurface = Color.Black, onSurfaceVariant = Color.Black, + error = Color(0xFFB3261E), + ) object NoRippleTheme : RippleTheme { From 097b3426ef05ecf2ca8d385c513f0abb3216fc09 Mon Sep 17 00:00:00 2001 From: Karan Joshi Date: Sat, 19 Jul 2025 22:52:33 +0530 Subject: [PATCH 08/10] Edit profile UI --- .../karan/hashin/screens/home/EditProfile.kt | 79 ++++++++++++++++++- 1 file changed, 76 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/karan/hashin/screens/home/EditProfile.kt b/app/src/main/java/com/karan/hashin/screens/home/EditProfile.kt index 8be94cf..404acab 100644 --- a/app/src/main/java/com/karan/hashin/screens/home/EditProfile.kt +++ b/app/src/main/java/com/karan/hashin/screens/home/EditProfile.kt @@ -32,8 +32,9 @@ import com.karan.hashin.ui.theme.HashinTheme fun EditProfileScreen() { var name by remember { mutableStateOf("") } var email by remember { mutableStateOf("") } + var phone by remember { mutableStateOf("") } + var bio by remember { mutableStateOf("") } - // Professional, neutral background Box( modifier = Modifier .fillMaxSize() @@ -85,7 +86,16 @@ fun EditProfileScreen() { color = Color(0xFF22223B), modifier = Modifier.padding(bottom = 18.dp) ) - // Name Field + // Section: Basic Info + Text( + text = "Basic Information", + fontSize = 15.sp, + fontWeight = FontWeight.Medium, + color = Color(0xFF6C6C6C), + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 6.dp) + ) OutlinedTextField( value = name, onValueChange = { name = it }, @@ -100,7 +110,6 @@ fun EditProfileScreen() { cursorColor = Color(0xFF22223B) ) ) - // Email Field OutlinedTextField( value = email, onValueChange = { email = it }, @@ -115,6 +124,70 @@ fun EditProfileScreen() { cursorColor = Color(0xFF22223B) ) ) + OutlinedTextField( + value = phone, + onValueChange = { phone = it }, + label = { Text("Phone Number") }, + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 4.dp), + shape = RoundedCornerShape(12.dp), + colors = OutlinedTextFieldDefaults.colors( + focusedBorderColor = Color(0xFF22223B), + unfocusedBorderColor = Color(0xFFE0E0E0), + cursorColor = Color(0xFF22223B) + ) + ) + Spacer(modifier = Modifier.height(10.dp)) + // Section: Bio + Text( + text = "Bio", + fontSize = 15.sp, + fontWeight = FontWeight.Medium, + color = Color(0xFF6C6C6C), + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 6.dp) + ) + OutlinedTextField( + value = bio, + onValueChange = { bio = it }, + label = { Text("Short Bio") }, + modifier = Modifier + .fillMaxWidth() + .height(90.dp) + .padding(vertical = 4.dp), + shape = RoundedCornerShape(12.dp), + colors = OutlinedTextFieldDefaults.colors( + focusedBorderColor = Color(0xFF22223B), + unfocusedBorderColor = Color(0xFFE0E0E0), + cursorColor = Color(0xFF22223B) + ), + maxLines = 3 + ) + Spacer(modifier = Modifier.height(18.dp)) + Divider(color = Color(0xFFE0E0E0), thickness = 1.dp) + Spacer(modifier = Modifier.height(14.dp)) + // Section: Security + Text( + text = "Security", + fontSize = 15.sp, + fontWeight = FontWeight.Medium, + color = Color(0xFF6C6C6C), + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 6.dp) + ) + Button( + onClick = { /* Change password action */ }, + modifier = Modifier + .fillMaxWidth() + .height(48.dp), + shape = RoundedCornerShape(12.dp), + colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF22223B)) + ) { + Text("Change Password", color = Color.White, fontWeight = FontWeight.Medium) + } Spacer(modifier = Modifier.height(22.dp)) Row( modifier = Modifier.fillMaxWidth(), From 0ae0f3da3d43c03e3d25dca67c9be197afd04f7e Mon Sep 17 00:00:00 2001 From: Karan Joshi Date: Sat, 26 Jul 2025 23:39:52 +0530 Subject: [PATCH 09/10] Edit Profile UI --- .../karan/hashin/screens/home/EditProfile.kt | 382 +++++++++--------- .../karan/hashin/screens/home/NewProfile.kt | 2 + 2 files changed, 203 insertions(+), 181 deletions(-) create mode 100644 app/src/main/java/com/karan/hashin/screens/home/NewProfile.kt diff --git a/app/src/main/java/com/karan/hashin/screens/home/EditProfile.kt b/app/src/main/java/com/karan/hashin/screens/home/EditProfile.kt index 404acab..2b125e9 100644 --- a/app/src/main/java/com/karan/hashin/screens/home/EditProfile.kt +++ b/app/src/main/java/com/karan/hashin/screens/home/EditProfile.kt @@ -1,218 +1,240 @@ package com.karan.hashin.screens.home -import com.karan.hashin.R -import androidx.compose.foundation.BorderStroke -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.* import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.* import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.AccountCircle -import androidx.compose.material.icons.filled.Edit +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.shadow -import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview -import com.karan.hashin.ui.theme.HashinTheme +import com.karan.hashin.R +@OptIn(ExperimentalMaterial3Api::class) @Composable fun EditProfileScreen() { - var name by remember { mutableStateOf("") } - var email by remember { mutableStateOf("") } - var phone by remember { mutableStateOf("") } - var bio by remember { mutableStateOf("") } + var name by remember { mutableStateOf("Tara Jain") } + var email by remember { mutableStateOf("tarajain18@gamil.com") } + var dobExpanded by remember { mutableStateOf(false) } + var countryExpanded by remember { mutableStateOf(false) } + val dobOptions = listOf("13/04/2004") + val countryOptions = listOf("Indore", "Delhi", "Mumbai", "Bangalore") + var selectedDob by remember { mutableStateOf(dobOptions[0]) } + var selectedCountry by remember { mutableStateOf(countryOptions[0]) } - Box( - modifier = Modifier - .fillMaxSize() - .background(Color(0xFFF7F7F7)) - ) { + Scaffold( + topBar = { + TopAppBar( + title = { + Text("Edit Profile", fontWeight = FontWeight.Bold, fontSize = 18.sp) + }, + navigationIcon = { + IconButton(onClick = { /* Handle back */ }) { + Icon(Icons.Default.ArrowBack, contentDescription = "Back") + } + }, + colors = TopAppBarDefaults.topAppBarColors( + containerColor = Color.White, + titleContentColor = Color.Black + ) + ) + }, + containerColor = Color.White, + bottomBar = { + Box( + Modifier + .fillMaxWidth() + .padding(16.dp) + ) { + Button( + onClick = { /* Save and continue */ }, + modifier = Modifier + .fillMaxWidth() + .height(52.dp), + shape = RoundedCornerShape(12.dp), + colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF2251FF)) + ) { + Text("Save And Continue", color = Color.White, fontWeight = FontWeight.SemiBold) + } + } + } + ) { innerPadding -> Column( modifier = Modifier .fillMaxSize() + .padding(innerPadding) .padding(horizontal = 24.dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center + horizontalAlignment = Alignment.CenterHorizontally ) { - Card( + Spacer(modifier = Modifier.height(24.dp)) + // Profile Image + Box( + modifier = Modifier + .size(90.dp) + .clip(CircleShape) + .background(Color(0xFFE0E0E0)), + contentAlignment = Alignment.Center + ) { + Icon( + painter = painterResource(id = R.drawable.ic_launcher_foreground), + contentDescription = "Profile Picture", + tint = Color.Unspecified, + modifier = Modifier.size(90.dp) + ) + } + Spacer(modifier = Modifier.height(24.dp)) + // Name + Text( + text = "Name", + fontSize = 15.sp, + fontWeight = FontWeight.Medium, + color = Color(0xFF6C6C6C), + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 4.dp) + ) + OutlinedTextField( + value = name, + onValueChange = { name = it }, + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 12.dp), + shape = RoundedCornerShape(12.dp), + singleLine = true, + colors = OutlinedTextFieldDefaults.colors( + focusedBorderColor = Color(0xFF2251FF), + unfocusedBorderColor = Color(0xFFE0E0E0), + cursorColor = Color(0xFF2251FF) + ) + ) + // Email + Text( + text = "Email", + fontSize = 15.sp, + fontWeight = FontWeight.Medium, + color = Color(0xFF6C6C6C), + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 4.dp) + ) + OutlinedTextField( + value = email, + onValueChange = { email = it }, + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 12.dp), + shape = RoundedCornerShape(12.dp), + singleLine = true, + colors = OutlinedTextFieldDefaults.colors( + focusedBorderColor = Color(0xFF2251FF), + unfocusedBorderColor = Color(0xFFE0E0E0), + cursorColor = Color(0xFF2251FF) + ) + ) + // Date of Birth + Text( + text = "Date of Birth", + fontSize = 15.sp, + fontWeight = FontWeight.Medium, + color = Color(0xFF6C6C6C), modifier = Modifier .fillMaxWidth() - .wrapContentHeight() - .shadow(6.dp, RoundedCornerShape(20.dp)), - shape = RoundedCornerShape(20.dp), - colors = CardDefaults.cardColors(containerColor = Color.White), - elevation = CardDefaults.cardElevation(4.dp), - border = BorderStroke(1.dp, Color(0xFFE0E0E0)) + .padding(bottom = 4.dp) + ) + ExposedDropdownMenuBox( + expanded = dobExpanded, + onExpandedChange = { dobExpanded = !dobExpanded }, + modifier = Modifier.fillMaxWidth() ) { - Column( + OutlinedTextField( + value = selectedDob, + onValueChange = {}, + readOnly = true, + label = null, + trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = dobExpanded) }, modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp, vertical = 32.dp), - horizontalAlignment = Alignment.CenterHorizontally + .menuAnchor() + .fillMaxWidth(), + shape = RoundedCornerShape(12.dp), + colors = OutlinedTextFieldDefaults.colors( + focusedBorderColor = Color(0xFF2251FF), + unfocusedBorderColor = Color(0xFFE0E0E0), + cursorColor = Color(0xFF2251FF) + ) + ) + ExposedDropdownMenu( + expanded = dobExpanded, + onDismissRequest = { dobExpanded = false } ) { - // Simple avatar - Box( - modifier = Modifier - .size(90.dp) - .clip(CircleShape) - .background(Color(0xFFE0E0E0)), - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Default.AccountCircle, - contentDescription = "Profile Picture", - tint = Color(0xFFB0B0B0), - modifier = Modifier.size(80.dp) + dobOptions.forEach { dob -> + DropdownMenuItem( + text = { Text(dob) }, + onClick = { + selectedDob = dob + dobExpanded = false + } ) } - Spacer(modifier = Modifier.height(18.dp)) - Text( - text = "Edit Profile", - fontSize = 22.sp, - fontWeight = FontWeight.SemiBold, - color = Color(0xFF22223B), - modifier = Modifier.padding(bottom = 18.dp) - ) - // Section: Basic Info - Text( - text = "Basic Information", - fontSize = 15.sp, - fontWeight = FontWeight.Medium, - color = Color(0xFF6C6C6C), - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 6.dp) - ) - OutlinedTextField( - value = name, - onValueChange = { name = it }, - label = { Text("Name") }, - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 4.dp), - shape = RoundedCornerShape(12.dp), - colors = OutlinedTextFieldDefaults.colors( - focusedBorderColor = Color(0xFF22223B), - unfocusedBorderColor = Color(0xFFE0E0E0), - cursorColor = Color(0xFF22223B) - ) - ) - OutlinedTextField( - value = email, - onValueChange = { email = it }, - label = { Text("Email") }, - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 4.dp), - shape = RoundedCornerShape(12.dp), - colors = OutlinedTextFieldDefaults.colors( - focusedBorderColor = Color(0xFF22223B), - unfocusedBorderColor = Color(0xFFE0E0E0), - cursorColor = Color(0xFF22223B) - ) + } + } + Spacer(modifier = Modifier.height(12.dp)) + // Country/Region + Text( + text = "Country/Region", + fontSize = 15.sp, + fontWeight = FontWeight.Medium, + color = Color(0xFF6C6C6C), + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 4.dp) + ) + ExposedDropdownMenuBox( + expanded = countryExpanded, + onExpandedChange = { countryExpanded = !countryExpanded }, + modifier = Modifier.fillMaxWidth() + ) { + OutlinedTextField( + value = selectedCountry, + onValueChange = {}, + readOnly = true, + label = null, + trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = countryExpanded) }, + modifier = Modifier + .menuAnchor() + .fillMaxWidth(), + shape = RoundedCornerShape(12.dp), + colors = OutlinedTextFieldDefaults.colors( + focusedBorderColor = Color(0xFF2251FF), + unfocusedBorderColor = Color(0xFFE0E0E0), + cursorColor = Color(0xFF2251FF) ) - OutlinedTextField( - value = phone, - onValueChange = { phone = it }, - label = { Text("Phone Number") }, - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 4.dp), - shape = RoundedCornerShape(12.dp), - colors = OutlinedTextFieldDefaults.colors( - focusedBorderColor = Color(0xFF22223B), - unfocusedBorderColor = Color(0xFFE0E0E0), - cursorColor = Color(0xFF22223B) + ) + ExposedDropdownMenu( + expanded = countryExpanded, + onDismissRequest = { countryExpanded = false } + ) { + countryOptions.forEach { country -> + DropdownMenuItem( + text = { Text(country) }, + onClick = { + selectedCountry = country + countryExpanded = false + } ) - ) - Spacer(modifier = Modifier.height(10.dp)) - // Section: Bio - Text( - text = "Bio", - fontSize = 15.sp, - fontWeight = FontWeight.Medium, - color = Color(0xFF6C6C6C), - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 6.dp) - ) - OutlinedTextField( - value = bio, - onValueChange = { bio = it }, - label = { Text("Short Bio") }, - modifier = Modifier - .fillMaxWidth() - .height(90.dp) - .padding(vertical = 4.dp), - shape = RoundedCornerShape(12.dp), - colors = OutlinedTextFieldDefaults.colors( - focusedBorderColor = Color(0xFF22223B), - unfocusedBorderColor = Color(0xFFE0E0E0), - cursorColor = Color(0xFF22223B) - ), - maxLines = 3 - ) - Spacer(modifier = Modifier.height(18.dp)) - Divider(color = Color(0xFFE0E0E0), thickness = 1.dp) - Spacer(modifier = Modifier.height(14.dp)) - // Section: Security - Text( - text = "Security", - fontSize = 15.sp, - fontWeight = FontWeight.Medium, - color = Color(0xFF6C6C6C), - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 6.dp) - ) - Button( - onClick = { /* Change password action */ }, - modifier = Modifier - .fillMaxWidth() - .height(48.dp), - shape = RoundedCornerShape(12.dp), - colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF22223B)) - ) { - Text("Change Password", color = Color.White, fontWeight = FontWeight.Medium) - } - Spacer(modifier = Modifier.height(22.dp)) - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(12.dp) - ) { - Button( - onClick = { /* Save action */ }, - modifier = Modifier.weight(1f), - shape = RoundedCornerShape(12.dp), - colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF22223B)) - ) { - Text("Save", color = Color.White, fontWeight = FontWeight.Medium) - } - OutlinedButton( - onClick = { /* Cancel action */ }, - modifier = Modifier.weight(1f), - shape = RoundedCornerShape(12.dp), - border = BorderStroke(1.5.dp, Color(0xFF22223B)), - colors = ButtonDefaults.outlinedButtonColors(contentColor = Color(0xFF22223B)) - ) { - Text("Cancel", fontWeight = FontWeight.Medium) - } } } } + Spacer(modifier = Modifier.height(32.dp)) } } } @@ -220,8 +242,6 @@ fun EditProfileScreen() { @Preview(showBackground = true) @Composable fun EditProfileScreenPreview() { - MaterialTheme { - EditProfileScreen() - } + EditProfileScreen() } diff --git a/app/src/main/java/com/karan/hashin/screens/home/NewProfile.kt b/app/src/main/java/com/karan/hashin/screens/home/NewProfile.kt new file mode 100644 index 0000000..220641f --- /dev/null +++ b/app/src/main/java/com/karan/hashin/screens/home/NewProfile.kt @@ -0,0 +1,2 @@ +package com.karan.hashin.screens.home + From c1f8e3e113b5d7077b4dc707d6a1cf0230323fdc Mon Sep 17 00:00:00 2001 From: Karan Joshi Date: Fri, 15 Aug 2025 14:06:36 +0530 Subject: [PATCH 10/10] Account Edit Screen --- .../karan/hashin/screens/home/EditProfile.kt | 247 ------------------ .../com/karan/hashin/screens/home/Settings.kt | 213 +++++++++------ 2 files changed, 134 insertions(+), 326 deletions(-) delete mode 100644 app/src/main/java/com/karan/hashin/screens/home/EditProfile.kt diff --git a/app/src/main/java/com/karan/hashin/screens/home/EditProfile.kt b/app/src/main/java/com/karan/hashin/screens/home/EditProfile.kt deleted file mode 100644 index 2b125e9..0000000 --- a/app/src/main/java/com/karan/hashin/screens/home/EditProfile.kt +++ /dev/null @@ -1,247 +0,0 @@ -package com.karan.hashin.screens.home - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowBack -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.compose.ui.tooling.preview.Preview -import com.karan.hashin.R - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun EditProfileScreen() { - var name by remember { mutableStateOf("Tara Jain") } - var email by remember { mutableStateOf("tarajain18@gamil.com") } - var dobExpanded by remember { mutableStateOf(false) } - var countryExpanded by remember { mutableStateOf(false) } - val dobOptions = listOf("13/04/2004") - val countryOptions = listOf("Indore", "Delhi", "Mumbai", "Bangalore") - var selectedDob by remember { mutableStateOf(dobOptions[0]) } - var selectedCountry by remember { mutableStateOf(countryOptions[0]) } - - Scaffold( - topBar = { - TopAppBar( - title = { - Text("Edit Profile", fontWeight = FontWeight.Bold, fontSize = 18.sp) - }, - navigationIcon = { - IconButton(onClick = { /* Handle back */ }) { - Icon(Icons.Default.ArrowBack, contentDescription = "Back") - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = Color.White, - titleContentColor = Color.Black - ) - ) - }, - containerColor = Color.White, - bottomBar = { - Box( - Modifier - .fillMaxWidth() - .padding(16.dp) - ) { - Button( - onClick = { /* Save and continue */ }, - modifier = Modifier - .fillMaxWidth() - .height(52.dp), - shape = RoundedCornerShape(12.dp), - colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF2251FF)) - ) { - Text("Save And Continue", color = Color.White, fontWeight = FontWeight.SemiBold) - } - } - } - ) { innerPadding -> - Column( - modifier = Modifier - .fillMaxSize() - .padding(innerPadding) - .padding(horizontal = 24.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Spacer(modifier = Modifier.height(24.dp)) - // Profile Image - Box( - modifier = Modifier - .size(90.dp) - .clip(CircleShape) - .background(Color(0xFFE0E0E0)), - contentAlignment = Alignment.Center - ) { - Icon( - painter = painterResource(id = R.drawable.ic_launcher_foreground), - contentDescription = "Profile Picture", - tint = Color.Unspecified, - modifier = Modifier.size(90.dp) - ) - } - Spacer(modifier = Modifier.height(24.dp)) - // Name - Text( - text = "Name", - fontSize = 15.sp, - fontWeight = FontWeight.Medium, - color = Color(0xFF6C6C6C), - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 4.dp) - ) - OutlinedTextField( - value = name, - onValueChange = { name = it }, - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 12.dp), - shape = RoundedCornerShape(12.dp), - singleLine = true, - colors = OutlinedTextFieldDefaults.colors( - focusedBorderColor = Color(0xFF2251FF), - unfocusedBorderColor = Color(0xFFE0E0E0), - cursorColor = Color(0xFF2251FF) - ) - ) - // Email - Text( - text = "Email", - fontSize = 15.sp, - fontWeight = FontWeight.Medium, - color = Color(0xFF6C6C6C), - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 4.dp) - ) - OutlinedTextField( - value = email, - onValueChange = { email = it }, - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 12.dp), - shape = RoundedCornerShape(12.dp), - singleLine = true, - colors = OutlinedTextFieldDefaults.colors( - focusedBorderColor = Color(0xFF2251FF), - unfocusedBorderColor = Color(0xFFE0E0E0), - cursorColor = Color(0xFF2251FF) - ) - ) - // Date of Birth - Text( - text = "Date of Birth", - fontSize = 15.sp, - fontWeight = FontWeight.Medium, - color = Color(0xFF6C6C6C), - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 4.dp) - ) - ExposedDropdownMenuBox( - expanded = dobExpanded, - onExpandedChange = { dobExpanded = !dobExpanded }, - modifier = Modifier.fillMaxWidth() - ) { - OutlinedTextField( - value = selectedDob, - onValueChange = {}, - readOnly = true, - label = null, - trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = dobExpanded) }, - modifier = Modifier - .menuAnchor() - .fillMaxWidth(), - shape = RoundedCornerShape(12.dp), - colors = OutlinedTextFieldDefaults.colors( - focusedBorderColor = Color(0xFF2251FF), - unfocusedBorderColor = Color(0xFFE0E0E0), - cursorColor = Color(0xFF2251FF) - ) - ) - ExposedDropdownMenu( - expanded = dobExpanded, - onDismissRequest = { dobExpanded = false } - ) { - dobOptions.forEach { dob -> - DropdownMenuItem( - text = { Text(dob) }, - onClick = { - selectedDob = dob - dobExpanded = false - } - ) - } - } - } - Spacer(modifier = Modifier.height(12.dp)) - // Country/Region - Text( - text = "Country/Region", - fontSize = 15.sp, - fontWeight = FontWeight.Medium, - color = Color(0xFF6C6C6C), - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 4.dp) - ) - ExposedDropdownMenuBox( - expanded = countryExpanded, - onExpandedChange = { countryExpanded = !countryExpanded }, - modifier = Modifier.fillMaxWidth() - ) { - OutlinedTextField( - value = selectedCountry, - onValueChange = {}, - readOnly = true, - label = null, - trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = countryExpanded) }, - modifier = Modifier - .menuAnchor() - .fillMaxWidth(), - shape = RoundedCornerShape(12.dp), - colors = OutlinedTextFieldDefaults.colors( - focusedBorderColor = Color(0xFF2251FF), - unfocusedBorderColor = Color(0xFFE0E0E0), - cursorColor = Color(0xFF2251FF) - ) - ) - ExposedDropdownMenu( - expanded = countryExpanded, - onDismissRequest = { countryExpanded = false } - ) { - countryOptions.forEach { country -> - DropdownMenuItem( - text = { Text(country) }, - onClick = { - selectedCountry = country - countryExpanded = false - } - ) - } - } - } - Spacer(modifier = Modifier.height(32.dp)) - } - } -} - -@Preview(showBackground = true) -@Composable -fun EditProfileScreenPreview() { - EditProfileScreen() -} - diff --git a/app/src/main/java/com/karan/hashin/screens/home/Settings.kt b/app/src/main/java/com/karan/hashin/screens/home/Settings.kt index 4b4f0f4..d589137 100644 --- a/app/src/main/java/com/karan/hashin/screens/home/Settings.kt +++ b/app/src/main/java/com/karan/hashin/screens/home/Settings.kt @@ -8,12 +8,14 @@ import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.gestures.scrollable import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.* +import androidx.compose.material.icons.outlined.Edit import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.runtime.saveable.rememberSaveable @@ -28,6 +30,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.window.Popup import androidx.lifecycle.viewmodel.compose.viewModel import com.karan.hashin.ui.theme.Blue import com.karan.hashin.ui.theme.HashinTheme @@ -35,7 +38,7 @@ import com.karan.hashin.viewmodel.HomeViewModel @Composable fun Settings( - viewModel: HomeViewModel, +// viewModel: HomeViewModel, modifier: Modifier = Modifier ) { val context = LocalContext.current @@ -52,68 +55,7 @@ fun Settings( .verticalScroll(scrollState) ) { // Profile Card - ElevatedCard( - elevation = CardDefaults.elevatedCardElevation(defaultElevation = 8.dp), - shape = RoundedCornerShape(24.dp), - colors = CardDefaults.elevatedCardColors( - containerColor = MaterialTheme.colorScheme.surface - ), - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 8.dp) - ) { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier.padding(24.dp) - ) { - Box( - contentAlignment = Alignment.Center, - modifier = Modifier - .size(100.dp) - .clip(CircleShape) - .background(MaterialTheme.colorScheme.tertiary) - ) { - Icon( - imageVector = Icons.Default.Person, - contentDescription = "Profile", - tint = Color.White, - modifier = Modifier.size(50.dp) - ) - } - Spacer(modifier = Modifier.height(20.dp)) - Text( - text = "John Doe", - style = MaterialTheme.typography.headlineMedium, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.onSurface - ) - Text( - text = "john.doe@example.com", - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f) - ) - Spacer(modifier = Modifier.height(20.dp)) - Button( - onClick = { /* Edit profile */ }, - modifier = Modifier - .fillMaxWidth() - .height(50.dp), - colors = ButtonDefaults.buttonColors( - containerColor = Blue - ), - shape = RoundedCornerShape(16.dp) - ) { - Icon( - imageVector = Icons.Default.Edit, - contentDescription = null, - tint = Color.White, - modifier = Modifier.size(24.dp) - ) - Spacer(modifier = Modifier.width(8.dp)) - Text("Edit Profile", style = MaterialTheme.typography.titleMedium, color = Color.White) - } - } - } + ProfileCard() // Settings Options Card ElevatedCard( @@ -169,20 +111,6 @@ fun Settings( ) } } - - Button( - onClick = { /* Sign out */ }, - colors = ButtonDefaults.buttonColors( - containerColor = MaterialTheme.colorScheme.error - ), - shape = RoundedCornerShape(16.dp), - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 32.dp) - .height(56.dp) - ) { - Text("Sign Out", style = MaterialTheme.typography.titleMedium, color = Color.White) - } } } @@ -228,11 +156,138 @@ private fun SettingsItem( } } + +@Composable +fun ProfileCard(modifier: Modifier = Modifier) { + ElevatedCard( + elevation = CardDefaults.elevatedCardElevation(defaultElevation = 8.dp), + shape = RoundedCornerShape(24.dp), + colors = CardDefaults.elevatedCardColors( + containerColor = MaterialTheme.colorScheme.surface + ), + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 8.dp) + ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier + .padding(top = 12.dp, bottom = 24.dp) + .padding(horizontal = 24.dp) + ) { + IconButton( + onClick = { }, + modifier = Modifier + .size(32.dp) + .align(Alignment.End) + ) { + Icon( + imageVector = Icons.Outlined.Edit, + contentDescription = "Edit info", + tint = MaterialTheme.colorScheme.primary + ) + } + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .fillMaxWidth() + ) { + Box( + contentAlignment = Alignment.Center, + modifier = Modifier + .size(80.dp) + .clip(CircleShape) + .background(MaterialTheme.colorScheme.tertiary) + ) { + Icon( + imageVector = Icons.Default.Person, + contentDescription = "Profile", + tint = Color.White, + modifier = Modifier.size(50.dp) + ) + } + Spacer(modifier = Modifier.height(20.dp)) + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier + .fillMaxWidth() + ) { + Text( + text = "John Doe", + style = MaterialTheme.typography.headlineMedium, + fontWeight = FontWeight.Bold, + color = MaterialTheme.colorScheme.onSurface + ) + Text( + text = "john.doe@example.com", + style = MaterialTheme.typography.bodyLarge, + color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f) + ) + } + + + } + Spacer(modifier = Modifier.height(24.dp)) + Button( + onClick = { /* Sign out */ }, + colors = ButtonDefaults.buttonColors( + containerColor = MaterialTheme.colorScheme.error + ), + shape = RoundedCornerShape(16.dp), + modifier = Modifier + .fillMaxWidth() + .height(56.dp) + ) { + Text("Sign Out", style = MaterialTheme.typography.titleMedium, color = Color.White) + } + } + } +} + +@Composable +fun AccountEditPopUp( + visible: Boolean, + onConfirm: () -> Unit, + onDismiss: () -> Unit +) { + if (visible) { + Popup() { + + } + } +} + +@Composable +fun SignOutAlert( + visible: Boolean, + onConfirm: () -> Unit, + onDismiss: () -> Unit +) { + if (visible) { + AlertDialog( + onDismissRequest = onDismiss, + title = { Text("Really !?") }, + text = { Text("Are you sure you want to sign out ?") }, + confirmButton = { + TextButton(onClick = onConfirm) { + Text("Sign Out", color = Color.Red) + } + }, + dismissButton = { + TextButton(onClick = onDismiss) { + Text("Cancel") + } + } + ) + } +} + @Preview(showBackground = true, showSystemUi = true, uiMode = Configuration.UI_MODE_NIGHT_NO) @Composable fun PreviewSettingsLight() { - MaterialTheme() { - Settings(viewModel()) + MaterialTheme { +// Settings(viewModel()) + Settings() } }