diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 8576986..700258b 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -59,6 +59,7 @@ dependencies { implementation(libs.androidx.ui.graphics) implementation(libs.androidx.ui.tooling.preview) implementation(libs.androidx.material3) + implementation(libs.androidx.constraintlayout.compose) testImplementation(libs.junit) androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) @@ -66,4 +67,6 @@ dependencies { androidTestImplementation(libs.androidx.ui.test.junit4) debugImplementation(libs.androidx.ui.tooling) debugImplementation(libs.androidx.ui.test.manifest) + + implementation(libs.androidx.material.icons.extended) } \ No newline at end of file diff --git a/android/app/src/main/java/by/eapp/musicroom/screens/login/LogInScreen.kt b/android/app/src/main/java/by/eapp/musicroom/screens/login/LogInScreen.kt new file mode 100644 index 0000000..74a4c73 --- /dev/null +++ b/android/app/src/main/java/by/eapp/musicroom/screens/login/LogInScreen.kt @@ -0,0 +1,159 @@ +package by.eapp.musicroom.screens.login + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.defaultMinSize +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.ElevatedButton +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.OutlinedTextFieldDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.VisualTransformation +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp + +@Composable +fun LogInScreen() { + var email by rememberSaveable { mutableStateOf("") } + var password by rememberSaveable { mutableStateOf("") } + + Column( + modifier = Modifier + .fillMaxSize() + .background(color = Color.Black) + .padding(20.dp), + horizontalAlignment = Alignment.Start, + ) { + Spacer(modifier = Modifier.height(70.dp)) + Text( + text = "Sign In", + fontSize = 50.sp, + color = Color.White, + fontWeight = FontWeight.Bold + ) + Spacer(modifier = Modifier.height(70.dp)) + + Text( + text = "Email", + modifier = Modifier.padding(bottom = 5.dp), + color = Color.White + ) + TextInputField( + value = email, + onValueChange = { email = it }, + placeholderText = "anastasizzzs10@gmail.com" + ) + Spacer(modifier = Modifier.height(40.dp)) + Text( + text = "Password", + modifier = Modifier.padding(bottom = 5.dp), + color = Color.White + ) + TextInputField( + value = email, + onValueChange = { email = it }, + placeholderText = "***********" + ) + Spacer(modifier = Modifier.height(40.dp)) + LogInButton( + enabled = true, + onClick = {} + ) + + } +} + +@Composable +fun LogInButton( + modifier: Modifier = Modifier, + enabled: Boolean = false, + onClick:() -> Unit, +) { + ElevatedButton( + onClick = onClick, + enabled = enabled, + shape = RoundedCornerShape(20), + colors = ButtonDefaults.elevatedButtonColors( + containerColor = if (enabled) Color.White else Color.LightGray, + contentColor = Color.Black + ), + modifier = modifier + .height(50.dp) + .fillMaxWidth() + .padding(horizontal = 16.dp) + ) { + Text( + text = "Register", + fontSize = 18.sp, + fontWeight = FontWeight.Bold + ) + } +} + +@Composable +fun TextInputField( + modifier: Modifier = Modifier, + value: String, + onValueChange: (String) -> Unit, + placeholderText: String, +) { + OutlinedTextField( + value = value, + onValueChange = onValueChange, + modifier = modifier + .fillMaxWidth() + .defaultMinSize(minHeight = 56.dp) + .height(50.dp), + placeholder = { + Text( + text = placeholderText, + ) + }, + shape = RoundedCornerShape(percent = 20), + + maxLines = 1, + visualTransformation = VisualTransformation.None, + keyboardOptions = KeyboardOptions.Default + ) +} + + +@Preview +@Composable +fun PreviewLogInScreen() { + LogInScreen() +} + +@Preview(showBackground = true) +@Composable +fun PreviewLogInButton() { + LogInButton(onClick = {}) +} + + +@Preview(showBackground = true) +@Composable +fun PreviewTextInputField() { + TextInputField( + value = "", + onValueChange = {}, + placeholderText = "placeholder" + ) +} \ No newline at end of file diff --git a/android/app/src/main/java/by/eapp/musicroom/screens/registration/RegistrationScreen.kt b/android/app/src/main/java/by/eapp/musicroom/screens/registration/RegistrationScreen.kt new file mode 100644 index 0000000..fba9f05 --- /dev/null +++ b/android/app/src/main/java/by/eapp/musicroom/screens/registration/RegistrationScreen.kt @@ -0,0 +1,175 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +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.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Visibility +import androidx.compose.material.icons.filled.VisibilityOff +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.input.PasswordVisualTransformation +import androidx.compose.ui.text.input.VisualTransformation +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.constraintlayout.compose.Visibility +import by.eapp.musicroom.screens.login.LogInButton +import by.eapp.musicroom.screens.login.TextInputField + +@Composable +fun RegistrationScreen() { + var nickname by rememberSaveable { mutableStateOf("") } + var email by rememberSaveable { mutableStateOf("") } + + var password by remember { mutableStateOf("") } + var repeatPassword by remember { mutableStateOf("") } + var showPassword by remember { mutableStateOf(false) } + var showRepeatPassword by remember { mutableStateOf(false) } + + Column( + modifier = Modifier + .fillMaxSize() + .background(color = Color.Black) + .padding(20.dp), + horizontalAlignment = Alignment.Start, + ) { + Spacer(modifier = Modifier.height(70.dp)) + Text( + text = "Sign Up", + fontSize = 50.sp, + color = Color.White, + fontWeight = FontWeight.Bold + ) + Spacer(modifier = Modifier.height(70.dp)) + + Text( + text = "Nickname", + modifier = Modifier.padding(bottom = 5.dp), + color = Color.White + ) + TextInputField( + value = nickname, + onValueChange = { nickname = it }, + placeholderText = "nastix123", + ) + Spacer(modifier = Modifier.height(40.dp)) + Text( + text = "Email", + modifier = Modifier.padding(bottom = 5.dp), + color = Color.White + ) + TextInputField( + value = email, + onValueChange = { email = it }, + placeholderText = "anastasizzzs10@gmail.com" + ) + //passwords + Spacer(modifier = Modifier.height(40.dp)) + Text( + text = "Password", + modifier = Modifier.padding(bottom = 5.dp), + color = Color.White + ) + PasswordTextInputField( + password = password, + onPasswordChange = { password = it }, + showPassword = showPassword, + onShowPasswordChange = { showPassword = it } + ) + + // Repeat password field + Spacer(modifier = Modifier.height(20.dp)) + Text( + text = "Repeat password", + modifier = Modifier.padding(bottom = 5.dp), + color = Color.White + ) + PasswordTextInputField( + password = repeatPassword, + onPasswordChange = { repeatPassword = it }, + showPassword = showRepeatPassword, + onShowPasswordChange = { showRepeatPassword = it } + ) + Spacer(modifier = Modifier.height(40.dp)) + LogInButton( + enabled = true, + onClick = {} + ) + } +} + +@Composable +fun PasswordTextInputField( + password: String, + onPasswordChange: (String) -> Unit, + modifier: Modifier = Modifier, + label: String = "Password", + placeholder: String = "Type password here", + showPasswordIcon: ImageVector = Icons.Filled.Visibility, + hidePasswordIcon: ImageVector = Icons.Filled.VisibilityOff, + showPassword: Boolean, + onShowPasswordChange: (Boolean) -> Unit +) { + OutlinedTextField( + modifier = modifier.fillMaxWidth(), + value = password, + onValueChange = onPasswordChange, + label = { Text(text = label) }, + placeholder = { Text(text = placeholder) }, + shape = RoundedCornerShape(percent = 20), + visualTransformation = if (showPassword) { + VisualTransformation.None + } else { + PasswordVisualTransformation() + }, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), + trailingIcon = { + IconButton(onClick = { onShowPasswordChange(!showPassword) }) { + Icon( + imageVector = if (showPassword) showPasswordIcon else hidePasswordIcon, + contentDescription = if (showPassword) "Hide password" else "Show password" + ) + } + } + ) +} + +@Preview(showBackground = true) +@Composable +fun PasswordTextInputFieldPreview() { + + var password by remember { mutableStateOf("") } + var showPassword by remember { mutableStateOf(false) } + + PasswordTextInputField( + password = password, + onPasswordChange = { password = it }, + showPassword = showPassword, + onShowPasswordChange = { showPassword = it } + ) +} + +@Preview +@Composable +fun RegistrationScreenPreview() { + RegistrationScreen() +} diff --git a/android/gradle/libs.versions.toml b/android/gradle/libs.versions.toml index c16a3e1..a3c8ce3 100644 --- a/android/gradle/libs.versions.toml +++ b/android/gradle/libs.versions.toml @@ -8,9 +8,12 @@ espressoCore = "3.6.1" lifecycleRuntimeKtx = "2.8.3" activityCompose = "1.9.0" composeBom = "2024.04.01" +constraintlayoutCompose = "1.0.1" +materialIconsExtended = "1.6.8" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } +androidx-material-icons-extended = { module = "androidx.compose.material:material-icons-extended", version.ref = "materialIconsExtended" } junit = { group = "junit", name = "junit", version.ref = "junit" } androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } @@ -24,6 +27,7 @@ androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-toolin androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } androidx-material3 = { group = "androidx.compose.material3", name = "material3" } +androidx-constraintlayout-compose = { group = "androidx.constraintlayout", name = "constraintlayout-compose", version.ref = "constraintlayoutCompose" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" }