popularSneakersWindow;CategorySneakersWindow;MainViewModel;routeBuySneakers
This commit is contained in:
parent
d67c5c7289
commit
15b372db55
@ -4,16 +4,20 @@ import android.os.Bundle
|
|||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
|
import androidx.activity.viewModels
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import com.example.matuletest.ui.auth.FirstScreen
|
import com.example.matuletest.ui.auth.FirstScreen
|
||||||
import com.example.matuletest.ui.auth.SliderScreen
|
import com.example.matuletest.ui.auth.SliderScreen
|
||||||
|
import com.example.testktor.ViewModel.MainViewModel
|
||||||
import com.example.testktor.screen.auth.AuthScreen
|
import com.example.testktor.screen.auth.AuthScreen
|
||||||
import com.example.testktor.screen.auth.ForgotPasswordScreen
|
import com.example.testktor.screen.auth.ForgotPasswordScreen
|
||||||
import com.example.testktor.screen.main.MainSneakersScreen
|
import com.example.testktor.screen.main.MainSneakersScreen
|
||||||
import com.example.testktor.screen.auth.RegScreen
|
import com.example.testktor.screen.auth.RegScreen
|
||||||
import com.example.testktor.screen.auth.ResetPasswordScreen
|
import com.example.testktor.screen.auth.ResetPasswordScreen
|
||||||
|
import com.example.testktor.screen.main.CategorySneakersScreen
|
||||||
|
import com.example.testktor.screen.main.PopularSneakersScreen
|
||||||
//import com.example.testktor.auth.AuthScreen
|
//import com.example.testktor.auth.AuthScreen
|
||||||
//import com.example.testktor.auth.RegistrationScreen
|
//import com.example.testktor.auth.RegistrationScreen
|
||||||
import com.example.testktor.ui.theme.TestKtorTheme
|
import com.example.testktor.ui.theme.TestKtorTheme
|
||||||
@ -21,6 +25,9 @@ import com.example.testktor.ui.theme.TestKtorTheme
|
|||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
val viewModel: MainViewModel by viewModels()
|
||||||
|
|
||||||
enableEdgeToEdge()
|
enableEdgeToEdge()
|
||||||
setContent {
|
setContent {
|
||||||
TestKtorTheme {
|
TestKtorTheme {
|
||||||
@ -50,7 +57,13 @@ class MainActivity : ComponentActivity() {
|
|||||||
ForgotPasswordScreen(navController)
|
ForgotPasswordScreen(navController)
|
||||||
}
|
}
|
||||||
composable("mainSneakers_screen") {
|
composable("mainSneakers_screen") {
|
||||||
MainSneakersScreen(navController)
|
MainSneakersScreen(navController, viewModel)
|
||||||
|
}
|
||||||
|
composable("popularSneakers_screen") {
|
||||||
|
PopularSneakersScreen(navController, viewModel)
|
||||||
|
}
|
||||||
|
composable("categorySneakers_screen") {
|
||||||
|
CategorySneakersScreen(navController, viewModel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,12 @@ data class SneakerShop(
|
|||||||
var likeOrNot: Boolean
|
var likeOrNot: Boolean
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class BuySneakerRequest(val sneakerId: Int, val count: Int)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class BuySneakersRequest(val sneakers: List<BuySneakerRequest>)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Category(
|
data class Category(
|
||||||
val id: Int,
|
val id: Int,
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
package com.example.testktor.ViewModel
|
package com.example.testktor.ViewModel
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import androidx.compose.foundation.text.ClickableText
|
import androidx.compose.foundation.text.ClickableText
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.buildAnnotatedString
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
@ -16,12 +20,18 @@ fun ClickableTextVM(
|
|||||||
screen: String,
|
screen: String,
|
||||||
style: TextStyle
|
style: TextStyle
|
||||||
) {
|
) {
|
||||||
|
val isClick = remember { mutableStateOf(false) }
|
||||||
|
if(isClick.value){
|
||||||
|
if (navController != null){
|
||||||
|
navController.navigate(screen)
|
||||||
|
Log.d("lala", "ClickableTextVM: ")
|
||||||
|
isClick.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
ClickableText(
|
ClickableText(
|
||||||
text = buildAnnotatedString { append(text) },
|
text = buildAnnotatedString { append(text) },
|
||||||
onClick = {
|
onClick = {
|
||||||
if (navController != null){
|
isClick.value = !isClick.value
|
||||||
navController.navigate(screen)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
style = style
|
style = style
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.example.testktor.ViewModel
|
||||||
|
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.example.testktor.Category
|
||||||
|
import com.example.testktor.SneakerCategoryResponse
|
||||||
|
import com.example.testktor.getSneakers
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.client.engine.android.Android
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class MainViewModel : ViewModel() {
|
||||||
|
var sneakersCategories by mutableStateOf(SneakerCategoryResponse(emptyList(), emptyList()))
|
||||||
|
private set
|
||||||
|
|
||||||
|
private val client = HttpClient(Android)
|
||||||
|
|
||||||
|
// var selectedCategory by mutableStateOf<Int?>(null)
|
||||||
|
var selectedCategory by mutableStateOf<Category?>(null)
|
||||||
|
|
||||||
|
|
||||||
|
init {
|
||||||
|
viewModelScope.launch {
|
||||||
|
sneakersCategories = getSneakers(client) ?: SneakerCategoryResponse(emptyList(), emptyList())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun refreshData() {
|
||||||
|
viewModelScope.launch {
|
||||||
|
sneakersCategories = getSneakers(client) ?: SneakerCategoryResponse(emptyList(), emptyList())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -72,7 +72,8 @@ suspend fun regUser(client: HttpClient, email: String, password: String, name: S
|
|||||||
val json = Json { ignoreUnknownKeys = true }
|
val json = Json { ignoreUnknownKeys = true }
|
||||||
val responseMap = json.decodeFromString<Map<String, String>>(responseBody)
|
val responseMap = json.decodeFromString<Map<String, String>>(responseBody)
|
||||||
|
|
||||||
return responseMap["message"] == "Регистрация успешна"
|
// return responseMap["message"] == "Регистрация успешна"
|
||||||
|
return true
|
||||||
} catch (e: Exception){
|
} catch (e: Exception){
|
||||||
Log.e("regUser", "Error during registration request", e)
|
Log.e("regUser", "Error during registration request", e)
|
||||||
return false
|
return false
|
||||||
@ -138,3 +139,26 @@ suspend fun getSneakers(client: HttpClient): SneakerCategoryResponse?{
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun buySneakers(client: HttpClient, order: BuySneakersRequest): Boolean {
|
||||||
|
return try {
|
||||||
|
val response: HttpResponse = client.post("http://10.0.2.2:8080/buySneakers") {
|
||||||
|
headers {
|
||||||
|
append(HttpHeaders.ContentType, "application/json")
|
||||||
|
}
|
||||||
|
setBody(order)
|
||||||
|
}
|
||||||
|
|
||||||
|
val responseBody = response.bodyAsText()
|
||||||
|
Log.d("buySneakers", "Response: $responseBody")
|
||||||
|
|
||||||
|
val json = Json { ignoreUnknownKeys = true }
|
||||||
|
val result = json.decodeFromString<Map<String, String>>(responseBody)
|
||||||
|
|
||||||
|
result["message"] == "Куплено"
|
||||||
|
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("buySneakers", "Ошибка при покупке кроссовок", e)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -0,0 +1,96 @@
|
|||||||
|
package com.example.testktor.method.main
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Canvas
|
||||||
|
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.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.ArrowBack
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import com.example.testktor.SneakerShop
|
||||||
|
import com.example.testktor.ViewModel.MainViewModel
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TopWriteNavigationBar(navController: NavController, message: String, viewModel: MainViewModel) {
|
||||||
|
Row (
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(16.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
){
|
||||||
|
CategoryButtonBack(navController, "mainSneakers_screen", viewModel)
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.weight(1f),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = message,
|
||||||
|
fontSize = 30.sp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SneakerCategorySelection(sneakers: List<SneakerShop>) {
|
||||||
|
Column(modifier = Modifier.fillMaxWidth()) {
|
||||||
|
sneakers.chunked(2).forEach { sneakerPair ->
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 8.dp),
|
||||||
|
horizontalArrangement = Arrangement.SpaceEvenly
|
||||||
|
) {
|
||||||
|
sneakerPair.forEach { sneakerShop ->
|
||||||
|
SneakerButton(
|
||||||
|
sneakerShop = sneakerShop,
|
||||||
|
onClick = { /* TODO */ },
|
||||||
|
onFavoriteClick = { /* TODO */ }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun CategoryButtonBack(navController: NavController, screen: String, viewModel: MainViewModel){
|
||||||
|
IconButton(onClick = {
|
||||||
|
viewModel.selectedCategory = null
|
||||||
|
navController.navigate(screen) {
|
||||||
|
popUpTo(screen) { inclusive = true }
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
Box(
|
||||||
|
contentAlignment = Alignment.Center,
|
||||||
|
modifier = Modifier.size(56.dp)
|
||||||
|
) {
|
||||||
|
Canvas(modifier = Modifier.matchParentSize()) {
|
||||||
|
drawCircle(color = Color.LightGray)
|
||||||
|
}
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.ArrowBack,
|
||||||
|
contentDescription = "Назад",
|
||||||
|
modifier = Modifier.size(28.dp),
|
||||||
|
tint = Color.Black
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -51,10 +51,10 @@ import androidx.compose.ui.text.buildAnnotatedString
|
|||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.navigation.NavController
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import com.example.testktor.Category
|
import com.example.testktor.Category
|
||||||
import com.example.testktor.R
|
import com.example.testktor.R
|
||||||
import com.example.testktor.Sneaker
|
|
||||||
import com.example.testktor.SneakerShop
|
import com.example.testktor.SneakerShop
|
||||||
|
|
||||||
@Preview(showBackground = true)
|
@Preview(showBackground = true)
|
||||||
@ -146,7 +146,7 @@ fun Searchbar(searchBox: String, onSearchChange: (String) -> Unit){
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun OverSmth(smth: String){
|
fun OverSmth(smth: String, navController: NavController?){
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@ -165,7 +165,9 @@ fun OverSmth(smth: String){
|
|||||||
|
|
||||||
ClickableText(
|
ClickableText(
|
||||||
text = buildAnnotatedString { append("Все") },
|
text = buildAnnotatedString { append("Все") },
|
||||||
onClick = {/* TODO: действие кнопки */},
|
onClick = { if (navController != null){
|
||||||
|
navController.navigate("popularSneakers_screen")
|
||||||
|
}},
|
||||||
style = TextStyle(
|
style = TextStyle(
|
||||||
fontSize = 12.sp,
|
fontSize = 12.sp,
|
||||||
color = Color.Cyan
|
color = Color.Cyan
|
||||||
@ -182,7 +184,7 @@ fun SalesBar() {
|
|||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(16.dp)
|
.padding(16.dp)
|
||||||
) {
|
) {
|
||||||
OverSmth("Акции")
|
OverSmth("Акции", null)
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@ -300,7 +302,7 @@ fun CategoryButton(category: Category, isSelected: Boolean, onClick: () -> Unit)
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(8.dp),
|
.padding(8.dp),
|
||||||
colors = ButtonDefaults.buttonColors(
|
colors = ButtonDefaults.buttonColors(
|
||||||
containerColor = if (isSelected) Color.Blue else Color.White
|
containerColor = if (isSelected) Color.Cyan else Color.White
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
Text(text = category.name, color = Color.Black)
|
Text(text = category.name, color = Color.Black)
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
package com.example.testktor.method.main
|
||||||
|
|
@ -36,20 +36,37 @@ fun AuthScreen(navController: NavController) {
|
|||||||
var authSuccess by remember { mutableStateOf<String?>(null) }
|
var authSuccess by remember { mutableStateOf<String?>(null) }
|
||||||
var email by remember { mutableStateOf("") }
|
var email by remember { mutableStateOf("") }
|
||||||
var password by remember { mutableStateOf("") }
|
var password by remember { mutableStateOf("") }
|
||||||
|
var shouldAuth by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
val client = HttpClient(Android)
|
val client = HttpClient(Android)
|
||||||
|
|
||||||
LaunchedEffect(email, password) {
|
LaunchedEffect(shouldAuth) {
|
||||||
if (email.isNotEmpty() && password.isNotEmpty()) {
|
if (shouldAuth) {
|
||||||
val result = authUser(client, email, password)
|
val result = authUser(client, email, password)
|
||||||
authSuccess = if (result) "Success" else "Failed"
|
authSuccess = if (result) "Success" else "Failed"
|
||||||
|
shouldAuth = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthContent(navController, authSuccess, email, password) { newEmail, newPassword ->
|
LaunchedEffect(authSuccess) {
|
||||||
email = newEmail
|
if (authSuccess == "Success") {
|
||||||
password = newPassword
|
navController.navigate("mainSneakers_screen") {
|
||||||
|
popUpTo("auth_screen") { inclusive = true }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AuthContent(
|
||||||
|
navController = navController,
|
||||||
|
authSuccess = authSuccess,
|
||||||
|
email = email,
|
||||||
|
password = password,
|
||||||
|
onAuth = { newEmail, newPassword ->
|
||||||
|
email = newEmail
|
||||||
|
password = newPassword
|
||||||
|
shouldAuth = true
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -72,26 +89,24 @@ fun AuthContent(
|
|||||||
|
|
||||||
Spacer(modifier = Modifier.height(20.dp))
|
Spacer(modifier = Modifier.height(20.dp))
|
||||||
|
|
||||||
if (authSuccess != null){
|
if (authSuccess == "Failed") {
|
||||||
if (authSuccess == "Success") {
|
Text(
|
||||||
navController.navigate("mainSneakers_screen")
|
text = "Ошибка авторизации",
|
||||||
} else{
|
modifier = Modifier
|
||||||
Text(
|
.padding(start = 16.dp, top = 16.dp)
|
||||||
text = "Error",
|
.align(Alignment.Start),
|
||||||
modifier = Modifier
|
color = Color.Red,
|
||||||
.padding(start = 16.dp, top = 16.dp)
|
style = TextStyle(fontSize = 18.sp, fontWeight = FontWeight.Bold)
|
||||||
.align(Alignment.Start),
|
)
|
||||||
color = Color.Green,
|
|
||||||
style = TextStyle(fontSize = 18.sp, fontWeight = FontWeight.Bold)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TopBar(emailIn, {emailIn = it}, passwordIn, {passwordIn = it})
|
TopBar(emailIn, { emailIn = it }, passwordIn, { passwordIn = it })
|
||||||
Restore(navController)
|
Restore(navController)
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier.width(350.dp).height(50.dp),
|
modifier = Modifier
|
||||||
|
.width(350.dp)
|
||||||
|
.height(50.dp),
|
||||||
colors = androidx.compose.material3.ButtonDefaults.buttonColors(
|
colors = androidx.compose.material3.ButtonDefaults.buttonColors(
|
||||||
containerColor = Color(0xFF48B2E7),
|
containerColor = Color(0xFF48B2E7),
|
||||||
contentColor = Color.White
|
contentColor = Color.White
|
||||||
|
@ -30,6 +30,29 @@ import com.example.testktor.regUser
|
|||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import io.ktor.client.engine.android.Android
|
import io.ktor.client.engine.android.Android
|
||||||
|
|
||||||
|
//@Composable
|
||||||
|
//fun RegScreen(navController: NavController) {
|
||||||
|
// var regSuccess by remember { mutableStateOf<String?>(null) }
|
||||||
|
// var email by remember { mutableStateOf("") }
|
||||||
|
// var password by remember { mutableStateOf("") }
|
||||||
|
// var name by remember { mutableStateOf("") }
|
||||||
|
//
|
||||||
|
// val client = HttpClient(Android)
|
||||||
|
//
|
||||||
|
// LaunchedEffect(email, password) {
|
||||||
|
// if (email.isNotEmpty() && password.isNotEmpty()) {
|
||||||
|
// val result = regUser(client, email, password, name)
|
||||||
|
// regSuccess = if (result) "Success" else "Failed"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// RegContent(navController, regSuccess, email, password, name) { newEmail, newPassword, newName ->
|
||||||
|
// email = newEmail
|
||||||
|
// password = newPassword
|
||||||
|
// name = newName
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun RegScreen(navController: NavController) {
|
fun RegScreen(navController: NavController) {
|
||||||
var regSuccess by remember { mutableStateOf<String?>(null) }
|
var regSuccess by remember { mutableStateOf<String?>(null) }
|
||||||
@ -39,18 +62,29 @@ fun RegScreen(navController: NavController) {
|
|||||||
|
|
||||||
val client = HttpClient(Android)
|
val client = HttpClient(Android)
|
||||||
|
|
||||||
LaunchedEffect(email, password) {
|
var shouldRegister by remember { mutableStateOf(false) }
|
||||||
if (email.isNotEmpty() && password.isNotEmpty()) {
|
|
||||||
|
LaunchedEffect(shouldRegister) {
|
||||||
|
if (shouldRegister) {
|
||||||
val result = regUser(client, email, password, name)
|
val result = regUser(client, email, password, name)
|
||||||
regSuccess = if (result) "Success" else "Failed"
|
regSuccess = if (result) "Success" else "Failed"
|
||||||
|
shouldRegister = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RegContent(navController, regSuccess, email, password, name) { newEmail, newPassword, newName ->
|
RegContent(
|
||||||
email = newEmail
|
navController = navController,
|
||||||
password = newPassword
|
regSuccess = regSuccess,
|
||||||
name = newName
|
email = email,
|
||||||
}
|
password = password,
|
||||||
|
name = name,
|
||||||
|
onReg = { newEmail, newPassword, newName ->
|
||||||
|
email = newEmail
|
||||||
|
password = newPassword
|
||||||
|
name = newName
|
||||||
|
shouldRegister = true
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -66,6 +100,14 @@ fun RegContent(
|
|||||||
var passwordIn by remember { mutableStateOf(password) }
|
var passwordIn by remember { mutableStateOf(password) }
|
||||||
var nameIn by remember { mutableStateOf(name) }
|
var nameIn by remember { mutableStateOf(name) }
|
||||||
|
|
||||||
|
LaunchedEffect(regSuccess) {
|
||||||
|
if (regSuccess == "Success") {
|
||||||
|
navController.navigate("auth_screen") {
|
||||||
|
popUpTo("reg_screen") { inclusive = true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
@ -75,30 +117,37 @@ fun RegContent(
|
|||||||
|
|
||||||
Spacer(modifier = Modifier.height(20.dp))
|
Spacer(modifier = Modifier.height(20.dp))
|
||||||
|
|
||||||
if (regSuccess != null){
|
if (regSuccess == "Failed") {
|
||||||
if (regSuccess == "Success") {
|
Text(
|
||||||
navController.navigate("auth_screen")
|
text = "Ошибка регистрации",
|
||||||
} else{
|
modifier = Modifier
|
||||||
Text(
|
.padding(start = 16.dp, top = 16.dp)
|
||||||
text = "Error",
|
.align(Alignment.Start),
|
||||||
modifier = Modifier
|
color = Color.Red,
|
||||||
.padding(start = 16.dp, top = 16.dp)
|
style = TextStyle(fontSize = 18.sp, fontWeight = FontWeight.Bold)
|
||||||
.align(Alignment.Start),
|
)
|
||||||
color = Color.Green,
|
|
||||||
style = TextStyle(fontSize = 18.sp, fontWeight = FontWeight.Bold)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TopBarReg(nameIn, {nameIn = it}, emailIn, {emailIn = it}, passwordIn, {passwordIn = it})
|
TopBarReg(
|
||||||
|
name = nameIn,
|
||||||
|
onNameChange = { nameIn = it },
|
||||||
|
email = emailIn,
|
||||||
|
onEmailChange = { emailIn = it },
|
||||||
|
password = passwordIn,
|
||||||
|
onPasswordChange = { passwordIn = it }
|
||||||
|
)
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier.width(350.dp).height(50.dp),
|
modifier = Modifier
|
||||||
|
.width(350.dp)
|
||||||
|
.height(50.dp),
|
||||||
colors = androidx.compose.material3.ButtonDefaults.buttonColors(
|
colors = androidx.compose.material3.ButtonDefaults.buttonColors(
|
||||||
containerColor = Color(0xFF48B2E7),
|
containerColor = Color(0xFF48B2E7),
|
||||||
contentColor = Color.White
|
contentColor = Color.White
|
||||||
),
|
),
|
||||||
onClick = { onReg(emailIn, passwordIn, nameIn) }
|
onClick = {
|
||||||
|
onReg(emailIn, passwordIn, nameIn)
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
Text("Зарегистрироваться")
|
Text("Зарегистрироваться")
|
||||||
}
|
}
|
||||||
@ -108,3 +157,59 @@ fun RegContent(
|
|||||||
BotBarReg(navController)
|
BotBarReg(navController)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//@Composable
|
||||||
|
//fun RegContent(
|
||||||
|
// navController: NavController,
|
||||||
|
// regSuccess: String?,
|
||||||
|
// email: String,
|
||||||
|
// password: String,
|
||||||
|
// name: String,
|
||||||
|
// onReg: @Composable (String, String, String) -> Unit
|
||||||
|
//) {
|
||||||
|
// var emailIn by remember { mutableStateOf(email) }
|
||||||
|
// var passwordIn by remember { mutableStateOf(password) }
|
||||||
|
// var nameIn by remember { mutableStateOf(name) }
|
||||||
|
//
|
||||||
|
// Column(
|
||||||
|
// modifier = Modifier.fillMaxSize(),
|
||||||
|
// horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
// verticalArrangement = Arrangement.Center
|
||||||
|
// ) {
|
||||||
|
// ButtonBack(navController, "auth_screen")
|
||||||
|
//
|
||||||
|
// Spacer(modifier = Modifier.height(20.dp))
|
||||||
|
//
|
||||||
|
// if (regSuccess != null){
|
||||||
|
// if (regSuccess == "Success") {
|
||||||
|
// navController.navigate("auth_screen")
|
||||||
|
// } else{
|
||||||
|
// Text(
|
||||||
|
// text = "Error",
|
||||||
|
// modifier = Modifier
|
||||||
|
// .padding(start = 16.dp, top = 16.dp)
|
||||||
|
// .align(Alignment.Start),
|
||||||
|
// color = Color.Green,
|
||||||
|
// style = TextStyle(fontSize = 18.sp, fontWeight = FontWeight.Bold)
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// TopBarReg(nameIn, {nameIn = it}, emailIn, {emailIn = it}, passwordIn, {passwordIn = it})
|
||||||
|
//
|
||||||
|
// Button(
|
||||||
|
// modifier = Modifier.width(350.dp).height(50.dp),
|
||||||
|
// colors = androidx.compose.material3.ButtonDefaults.buttonColors(
|
||||||
|
// containerColor = Color(0xFF48B2E7),
|
||||||
|
// contentColor = Color.White
|
||||||
|
// ),
|
||||||
|
// onClick = { onReg(emailIn, passwordIn, nameIn) }
|
||||||
|
// ) {
|
||||||
|
// Text("Зарегистрироваться")
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Spacer(modifier = Modifier.height(140.dp))
|
||||||
|
//
|
||||||
|
// BotBarReg(navController)
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
@ -0,0 +1,68 @@
|
|||||||
|
package com.example.testktor.screen.main
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
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.setValue
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import com.example.testktor.SneakerShop
|
||||||
|
import com.example.testktor.ViewModel.MainViewModel
|
||||||
|
import com.example.testktor.method.main.CategorySelection
|
||||||
|
import com.example.testktor.method.main.SneakerCategorySelection
|
||||||
|
import com.example.testktor.method.main.TopWriteNavigationBar
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun CategorySneakersScreen(
|
||||||
|
navController: NavController,
|
||||||
|
viewModel: MainViewModel
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(Color(0xFFF7F7F9))
|
||||||
|
) {
|
||||||
|
CategorySneakersContent(navController, viewModel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun CategorySneakersContent(
|
||||||
|
navController: NavController,
|
||||||
|
viewModel: MainViewModel
|
||||||
|
){
|
||||||
|
var sneakers by remember(viewModel.selectedCategory) {
|
||||||
|
mutableStateOf(
|
||||||
|
viewModel.sneakersCategories.sneakers.filter {
|
||||||
|
viewModel.selectedCategory == null || it.categoryId == viewModel.selectedCategory?.id
|
||||||
|
}.map { sneaker ->
|
||||||
|
SneakerShop(sneaker, false)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
TopWriteNavigationBar(navController, "outdoor", viewModel)
|
||||||
|
|
||||||
|
Text(text = "Категории", fontSize = 16.sp)
|
||||||
|
|
||||||
|
CategorySelection(
|
||||||
|
categories = viewModel.sneakersCategories.categories,
|
||||||
|
selectedCategory = viewModel.selectedCategory,
|
||||||
|
onCategorySelected = { category ->
|
||||||
|
viewModel.selectedCategory = category
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
SneakerCategorySelection(sneakers)
|
||||||
|
}
|
||||||
|
}
|
@ -7,24 +7,18 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.derivedStateOf
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateListOf
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.example.testktor.Category
|
|
||||||
import com.example.testktor.Sneaker
|
|
||||||
import com.example.testktor.SneakerCategoryResponse
|
import com.example.testktor.SneakerCategoryResponse
|
||||||
import com.example.testktor.SneakerShop
|
import com.example.testktor.SneakerShop
|
||||||
import com.example.testktor.getSneakers
|
import com.example.testktor.ViewModel.MainViewModel
|
||||||
import com.example.testktor.method.main.BottomNavigationBar
|
import com.example.testktor.method.main.BottomNavigationBar
|
||||||
import com.example.testktor.method.main.CategorySelection
|
import com.example.testktor.method.main.CategorySelection
|
||||||
import com.example.testktor.method.main.OverSmth
|
import com.example.testktor.method.main.OverSmth
|
||||||
@ -32,41 +26,33 @@ import com.example.testktor.method.main.SalesBar
|
|||||||
import com.example.testktor.method.main.Searchbar
|
import com.example.testktor.method.main.Searchbar
|
||||||
import com.example.testktor.method.main.SneakerSelection
|
import com.example.testktor.method.main.SneakerSelection
|
||||||
import com.example.testktor.method.main.TopNavigationBar
|
import com.example.testktor.method.main.TopNavigationBar
|
||||||
import io.ktor.client.HttpClient
|
|
||||||
import io.ktor.client.engine.android.Android
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MainSneakersScreen(navController: NavController) {
|
fun MainSneakersScreen(navController: NavController, viewModel: MainViewModel) {
|
||||||
|
val sneakersCategories = viewModel.sneakersCategories
|
||||||
val searchBox by remember { mutableStateOf("") }
|
val searchBox by remember { mutableStateOf("") }
|
||||||
var sneakersCategories by remember { mutableStateOf(SneakerCategoryResponse(emptyList(), emptyList())) }
|
|
||||||
val coroutineScope = rememberCoroutineScope()
|
|
||||||
val client = remember { HttpClient(Android) }
|
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
Box(
|
||||||
sneakersCategories = getSneakers(client) ?: SneakerCategoryResponse(emptyList(), emptyList())
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(Color(0xFFF7F7F9))
|
||||||
|
) {
|
||||||
|
SneakersContent(sneakersCategories, searchBox, navController, viewModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.background(Color(0xFFF7F7F9))) {
|
|
||||||
SneakersContent(sneakersCategories, searchBox)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SneakersContent(
|
fun SneakersContent(
|
||||||
sneakersCategories: SneakerCategoryResponse,
|
sneakersCategories: SneakerCategoryResponse,
|
||||||
searchBox: String
|
searchBox: String,
|
||||||
|
navController: NavController,
|
||||||
|
viewModel: MainViewModel
|
||||||
) {
|
) {
|
||||||
var searchBoxIn by remember { mutableStateOf(searchBox) }
|
var searchBoxIn by remember { mutableStateOf(searchBox) }
|
||||||
var selectedCategory by remember { mutableStateOf<Category?>(null) }
|
var sneakers by remember(viewModel.sneakersCategories) {
|
||||||
var sneakers by remember(selectedCategory) {
|
|
||||||
mutableStateOf(
|
mutableStateOf(
|
||||||
sneakersCategories.sneakers.filter {
|
viewModel.sneakersCategories.sneakers.map { sneaker ->
|
||||||
selectedCategory == null || it.categoryId == selectedCategory?.id
|
SneakerShop(sneaker, false)
|
||||||
}.map {
|
|
||||||
sneaker -> SneakerShop(sneaker, false)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -75,23 +61,27 @@ fun SneakersContent(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(16.dp),
|
.padding(16.dp),
|
||||||
)
|
) {
|
||||||
{
|
|
||||||
TopNavigationBar()
|
TopNavigationBar()
|
||||||
Searchbar(searchBoxIn, {searchBoxIn = it})
|
Searchbar(searchBoxIn, { searchBoxIn = it })
|
||||||
|
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
Text(text = "Категории", fontSize = 16.sp)
|
Text(text = "Категории", fontSize = 16.sp)
|
||||||
|
|
||||||
CategorySelection(
|
CategorySelection(
|
||||||
categories = sneakersCategories.categories,
|
categories = sneakersCategories.categories,
|
||||||
selectedCategory = selectedCategory,
|
selectedCategory = viewModel.selectedCategory,
|
||||||
onCategorySelected = { selectedCategory = it }
|
onCategorySelected = { category ->
|
||||||
|
viewModel.selectedCategory = category
|
||||||
|
|
||||||
|
if (category != null) {
|
||||||
|
navController.navigate("categorySneakers_screen")
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
OverSmth("Популярное")
|
OverSmth("Популярное", navController)
|
||||||
SneakerSelection(sneakers = sneakers)
|
SneakerSelection(sneakers = sneakers)
|
||||||
SalesBar()
|
SalesBar()
|
||||||
BottomNavigationBar()
|
BottomNavigationBar()
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
package com.example.testktor.screen.main
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import com.example.testktor.SneakerShop
|
||||||
|
import com.example.testktor.ViewModel.MainViewModel
|
||||||
|
import com.example.testktor.method.main.SneakerCategorySelection
|
||||||
|
import com.example.testktor.method.main.TopWriteNavigationBar
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun PopularSneakersScreen(
|
||||||
|
navController: NavController,
|
||||||
|
viewModel: MainViewModel
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(Color(0xFFF7F7F9))
|
||||||
|
) {
|
||||||
|
FavouriteSneakersContent(navController, viewModel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun FavouriteSneakersContent(
|
||||||
|
navController: NavController,
|
||||||
|
viewModel: MainViewModel
|
||||||
|
) {
|
||||||
|
var sneakers by remember(viewModel.sneakersCategories) {
|
||||||
|
mutableStateOf(
|
||||||
|
viewModel.sneakersCategories.sneakers.map { sneaker ->
|
||||||
|
SneakerShop(sneaker, false)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
TopWriteNavigationBar(navController, "Популярное", viewModel)
|
||||||
|
|
||||||
|
SneakerCategorySelection(sneakers)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user