screens_methods
@ -90,4 +90,6 @@ dependencies {
|
|||||||
implementation(platform("io.github.jan-tennert.supabase:bom:3.0.3"))
|
implementation(platform("io.github.jan-tennert.supabase:bom:3.0.3"))
|
||||||
implementation("io.github.jan-tennert.supabase:postgrest-kt")
|
implementation("io.github.jan-tennert.supabase:postgrest-kt")
|
||||||
implementation("io.ktor:ktor-client-android:3.0.3")
|
implementation("io.ktor:ktor-client-android:3.0.3")
|
||||||
|
|
||||||
|
implementation("io.coil-kt:coil-compose:2.4.0")
|
||||||
}
|
}
|
@ -1,18 +1,9 @@
|
|||||||
package com.example.testktor
|
package com.example.testktor
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
|
||||||
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.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
|
||||||
import androidx.compose.runtime.*
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
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
|
||||||
@ -20,25 +11,12 @@ 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.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.auth.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.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
|
||||||
import io.ktor.client.*
|
|
||||||
import io.ktor.client.request.*
|
|
||||||
import io.ktor.client.engine.android.*
|
|
||||||
import io.ktor.client.plugins.contentnegotiation.*
|
|
||||||
import io.ktor.client.statement.HttpResponse
|
|
||||||
import io.ktor.client.statement.bodyAsText
|
|
||||||
import io.ktor.http.ContentType
|
|
||||||
import io.ktor.http.contentType
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
import io.ktor.serialization.kotlinx.json.*
|
|
||||||
import kotlinx.serialization.decodeFromString
|
|
||||||
import kotlinx.serialization.json.Json
|
|
||||||
|
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
45
app/src/main/java/com/example/testktor/Models.kt
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package com.example.testktor
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class User(
|
||||||
|
val id: Int,
|
||||||
|
val name: String,
|
||||||
|
val email: String,
|
||||||
|
val password: String,
|
||||||
|
val resetToken: String)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Sneaker(
|
||||||
|
val id: Int,
|
||||||
|
val name: String,
|
||||||
|
val description: String,
|
||||||
|
val cost: Double,
|
||||||
|
val discount: Int,
|
||||||
|
val photo: String,
|
||||||
|
val gender: Char,
|
||||||
|
val bootSize: Int,
|
||||||
|
val categoryId: Int
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SneakerShop(
|
||||||
|
val sneaker: Sneaker,
|
||||||
|
var likeOrNot: Boolean
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Category(
|
||||||
|
val id: Int,
|
||||||
|
val name: String,
|
||||||
|
val description: String
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SneakerCategoryResponse(
|
||||||
|
val sneakers: List<Sneaker>,
|
||||||
|
val categories: List<Category>
|
||||||
|
)
|
||||||
|
|
||||||
|
var Token: String = "";
|
@ -34,40 +34,6 @@ import kotlinx.serialization.json.Json
|
|||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.sql.Time
|
import java.sql.Time
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class User(
|
|
||||||
val id: Int,
|
|
||||||
val name: String,
|
|
||||||
val email: String,
|
|
||||||
val password: String,
|
|
||||||
val resetToken: String)
|
|
||||||
|
|
||||||
//@Serializable
|
|
||||||
//data class Sneaker(
|
|
||||||
// val id: Int,
|
|
||||||
// val name: String,
|
|
||||||
// val description: String,
|
|
||||||
// @Contextual val cost: BigDecimal,
|
|
||||||
// val discount: Int,
|
|
||||||
// val photo: String,
|
|
||||||
// val gender: Char,
|
|
||||||
// val bootSize: Int
|
|
||||||
//)
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class Sneaker(
|
|
||||||
val id: Int,
|
|
||||||
val name: String,
|
|
||||||
val description: String,
|
|
||||||
val cost: Double,
|
|
||||||
val discount: Int,
|
|
||||||
val photo: String,
|
|
||||||
val gender: Char,
|
|
||||||
val bootSize: Int
|
|
||||||
)
|
|
||||||
|
|
||||||
var Token: String = "";
|
|
||||||
|
|
||||||
suspend fun authUser(client: HttpClient, email: String, password: String): Boolean {
|
suspend fun authUser(client: HttpClient, email: String, password: String): Boolean {
|
||||||
try {
|
try {
|
||||||
val response: HttpResponse = client.post("http://10.0.2.2:8080/login") {
|
val response: HttpResponse = client.post("http://10.0.2.2:8080/login") {
|
||||||
@ -153,8 +119,8 @@ suspend fun resetPassword(client: HttpClient, code: String, newPassword: String)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getSneakers(client: HttpClient): List<Sneaker>{
|
suspend fun getSneakers(client: HttpClient): SneakerCategoryResponse?{
|
||||||
try {
|
return try {
|
||||||
val response: HttpResponse = client.get("http://10.0.2.2:8080/mainWindow") {
|
val response: HttpResponse = client.get("http://10.0.2.2:8080/mainWindow") {
|
||||||
headers {
|
headers {
|
||||||
append(HttpHeaders.Authorization, "Bearer $Token")
|
append(HttpHeaders.Authorization, "Bearer $Token")
|
||||||
@ -165,11 +131,10 @@ suspend fun getSneakers(client: HttpClient): List<Sneaker>{
|
|||||||
Log.d("getSneakers", "Response: $responseBody")
|
Log.d("getSneakers", "Response: $responseBody")
|
||||||
|
|
||||||
val json = Json { ignoreUnknownKeys = true }
|
val json = Json { ignoreUnknownKeys = true }
|
||||||
val responseMap = json.decodeFromString<Map<String, List<Sneaker>>>(responseBody)
|
json.decodeFromString<SneakerCategoryResponse>(responseBody)
|
||||||
|
|
||||||
return responseMap["sneakers"] ?: emptyList()
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e("getSneakers", "error fetching sneakers", e)
|
Log.e("getSneakers", "error fetching sneakers or category", e)
|
||||||
return emptyList()
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,166 @@
|
|||||||
|
package com.example.testktor.method.auth
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Canvas
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
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.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.foundation.text.ClickableText
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.ArrowBack
|
||||||
|
import androidx.compose.material.icons.filled.Lock
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextField
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||||
|
import androidx.compose.ui.text.input.VisualTransformation
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ButtonBack(navController: NavController){
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(start = 20.dp, top = 20.dp),
|
||||||
|
horizontalArrangement = Arrangement.Start
|
||||||
|
) {
|
||||||
|
IconButton(onClick = { navController.navigate("slider_screen") }) {
|
||||||
|
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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TopBar(email: String,
|
||||||
|
onEmailChange: (String) -> Unit,
|
||||||
|
password: String,
|
||||||
|
onPasswordChange: (String) -> Unit
|
||||||
|
){
|
||||||
|
var passwordVisible by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = "Привет!",
|
||||||
|
style = TextStyle(fontSize = 32.sp, fontWeight = FontWeight.Bold),
|
||||||
|
modifier = Modifier.height(60.dp).padding(bottom = 8.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = "Заполните Свои Данные Или Продолжите Через Социальные Медиа",
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(bottom = 20.dp),
|
||||||
|
style = TextStyle(fontSize = 16.sp),
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
maxLines = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(text = "Email", modifier = Modifier.padding(end = 280.dp))
|
||||||
|
TextField(
|
||||||
|
modifier = Modifier.width(350.dp).height(70.dp).padding(bottom = 16.dp),
|
||||||
|
value = email,
|
||||||
|
onValueChange = { onEmailChange(it)},
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(text = "Password", modifier = Modifier.padding(end = 250.dp))
|
||||||
|
TextField(
|
||||||
|
modifier = Modifier.width(350.dp).height(70.dp).padding(bottom = 16.dp),
|
||||||
|
value = password,
|
||||||
|
onValueChange = {onPasswordChange(it)},
|
||||||
|
visualTransformation = if (!passwordVisible) PasswordVisualTransformation() else VisualTransformation.None,
|
||||||
|
trailingIcon = {
|
||||||
|
IconButton(onClick = { passwordVisible = !passwordVisible }) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Lock,
|
||||||
|
contentDescription = "Lock",
|
||||||
|
tint = Color.Gray
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Restore(navController: NavController) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(top = 6.dp, bottom = 20.dp, end = 16.dp),
|
||||||
|
horizontalArrangement = Arrangement.End
|
||||||
|
) {
|
||||||
|
ClickableText(
|
||||||
|
text = buildAnnotatedString { append("Восстановить") },
|
||||||
|
onClick = {
|
||||||
|
navController.navigate("forgotPassword_screen")
|
||||||
|
},
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
color = Color.LightGray
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun BotBar(navController: NavController) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(16.dp)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.BottomCenter)
|
||||||
|
.padding(bottom = 16.dp),
|
||||||
|
horizontalArrangement = Arrangement.Center
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "Вы впервые? ",
|
||||||
|
style = TextStyle(fontSize = 16.sp, color = Color.Gray)
|
||||||
|
)
|
||||||
|
|
||||||
|
ClickableText(
|
||||||
|
text = buildAnnotatedString { append("Создать пользователя") },
|
||||||
|
onClick = {
|
||||||
|
navController.navigate("registration_screen")
|
||||||
|
},
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
color = Color.Black
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package com.example.testktor.method.auth
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.material3.Slider
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.text.font.FontStyle
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Textik(imageId: Int, textList: List<String>, textList2: List<String>, currentIndex: Int){
|
||||||
|
Image(
|
||||||
|
painter = painterResource(id = imageId),
|
||||||
|
contentDescription = "Изображение",
|
||||||
|
modifier = androidx.compose.ui.Modifier.width(670.dp).height(600.dp).padding(start = 20.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
color = Color.White,
|
||||||
|
fontStyle = FontStyle.Italic,
|
||||||
|
text = textList[currentIndex],
|
||||||
|
fontSize = 24.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
modifier = androidx.compose.ui.Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(top = 40.dp)
|
||||||
|
.width(700.dp).height(30.dp)
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
color = Color.White,
|
||||||
|
fontStyle = FontStyle.Italic,
|
||||||
|
text = textList2[currentIndex],
|
||||||
|
fontSize = 18.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
modifier = androidx.compose.ui.Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(top = 40.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Sliderik(sliderValue: Float, maxIndex: Int, onClick: (Float) -> Unit, ){
|
||||||
|
Slider(
|
||||||
|
value = sliderValue,
|
||||||
|
onValueChange = onClick,
|
||||||
|
valueRange = 0f..maxIndex.toFloat(),
|
||||||
|
steps = maxIndex - 1,
|
||||||
|
colors = androidx.compose.material3.SliderDefaults.colors(
|
||||||
|
thumbColor = Color.White,
|
||||||
|
activeTrackColor = Color(0xFF0076B1),
|
||||||
|
inactiveTrackColor = Color(0xFFB0B0B0)
|
||||||
|
),
|
||||||
|
modifier = androidx.compose.ui.Modifier.fillMaxWidth()
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package com.example.testktor.method.auth
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextField
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun BarForgot(emailIn: String, onEmailChane: (String) -> Unit){
|
||||||
|
Text(
|
||||||
|
text = "Забыл Пароль",
|
||||||
|
style = TextStyle(fontSize = 32.sp, fontWeight = FontWeight.Bold),
|
||||||
|
modifier = Modifier.height(60.dp).padding(bottom = 20.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = "Введите свою учетную запись для сброса",
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(bottom = 20.dp),
|
||||||
|
style = TextStyle(fontSize = 16.sp),
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
maxLines = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(text = "Email", modifier = Modifier.padding(end = 255.dp))
|
||||||
|
TextField(
|
||||||
|
modifier = Modifier.width(300.dp).height(70.dp).padding(bottom = 16.dp),
|
||||||
|
value = emailIn,
|
||||||
|
onValueChange = {onEmailChane(it)}
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,163 @@
|
|||||||
|
package com.example.testktor.method.auth
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
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.padding
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.foundation.text.ClickableText
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.Lock
|
||||||
|
import androidx.compose.material3.Checkbox
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextField
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.text.SpanStyle
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||||
|
import androidx.compose.ui.text.input.VisualTransformation
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.text.style.TextDecoration
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TopBarReg(name: String,
|
||||||
|
onNameChange: (String) -> Unit,
|
||||||
|
email: String,
|
||||||
|
onEmailChange: (String) -> Unit,
|
||||||
|
password: String,
|
||||||
|
onPasswordChange: (String) -> Unit
|
||||||
|
){
|
||||||
|
var passwordVisible by remember { mutableStateOf(false) }
|
||||||
|
var isChecked by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = "Регистрация",
|
||||||
|
style = TextStyle(fontSize = 32.sp, fontWeight = FontWeight.Bold),
|
||||||
|
modifier = Modifier.height(60.dp).padding(bottom = 20.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = "Заполните Свои данные или продолжите через социальные медиа",
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(bottom = 20.dp),
|
||||||
|
style = TextStyle(fontSize = 16.sp),
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
maxLines = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(text = "Ваше имя", modifier = Modifier.padding(end = 270.dp))
|
||||||
|
TextField(
|
||||||
|
modifier = Modifier.width(350.dp).height(70.dp).padding(bottom = 16.dp),
|
||||||
|
value = name,
|
||||||
|
onValueChange = {onNameChange(it)}
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(text = "Email", modifier = Modifier.padding(end = 290.dp))
|
||||||
|
TextField(
|
||||||
|
modifier = Modifier.width(350.dp).height(70.dp).padding(bottom = 16.dp),
|
||||||
|
value = email,
|
||||||
|
onValueChange = {onEmailChange(it)}
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(text = "Password", modifier = Modifier.padding(end = 260.dp))
|
||||||
|
TextField(
|
||||||
|
modifier = Modifier.width(350.dp).height(70.dp).padding(bottom = 16.dp),
|
||||||
|
value = password,
|
||||||
|
onValueChange = {onPasswordChange(it)},
|
||||||
|
visualTransformation = if (!passwordVisible) PasswordVisualTransformation() else VisualTransformation.None,
|
||||||
|
trailingIcon = {
|
||||||
|
IconButton(onClick = { passwordVisible = !passwordVisible }) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Lock,
|
||||||
|
contentDescription = "Lock",
|
||||||
|
tint = Color.Gray
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(16.dp),
|
||||||
|
horizontalArrangement = Arrangement.Start,
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Checkbox(
|
||||||
|
checked = isChecked,
|
||||||
|
onCheckedChange = { isChecked = it }
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
|
||||||
|
ClickableText(
|
||||||
|
text = buildAnnotatedString {
|
||||||
|
append("Даю согласие на обработку персональных данных")
|
||||||
|
addStyle(
|
||||||
|
style = SpanStyle(
|
||||||
|
color = Color.Black,
|
||||||
|
textDecoration = TextDecoration.Underline
|
||||||
|
),
|
||||||
|
start = 0,
|
||||||
|
end = this.length
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onClick = { /* */ },
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(bottom = 20.dp),
|
||||||
|
style = TextStyle(fontSize = 16.sp, textAlign = TextAlign.Center)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun BotBarReg(navController: NavController) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(16.dp)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.BottomCenter)
|
||||||
|
.padding(bottom = 16.dp),
|
||||||
|
horizontalArrangement = Arrangement.Center
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "Есть аккаунт? ",
|
||||||
|
style = TextStyle(fontSize = 16.sp, color = Color.Gray)
|
||||||
|
)
|
||||||
|
|
||||||
|
ClickableText(
|
||||||
|
text = buildAnnotatedString { append("Войти") },
|
||||||
|
onClick = {
|
||||||
|
navController.navigate("auth_screen")
|
||||||
|
},
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
color = Color.Black
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
package com.example.testktor.method.auth
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextField
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TopBarReset(){
|
||||||
|
Text(
|
||||||
|
text = "ОТР Проверка",
|
||||||
|
style = TextStyle(fontSize = 32.sp, fontWeight = FontWeight.Bold),
|
||||||
|
modifier = Modifier.height(60.dp).padding(bottom = 20.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = "Пожалуйста, проверьте свою электронную почту, чтобы увидеть код подтверждения",
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(bottom = 20.dp),
|
||||||
|
style = TextStyle(fontSize = 16.sp),
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
maxLines = 3
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TextFieldsReset(codeIn: String,
|
||||||
|
onCodeChange: (String) -> Unit,
|
||||||
|
newPassword: String,
|
||||||
|
onNewPasswordChange: (String) -> Unit){
|
||||||
|
Text(text = "OTP Code", modifier = Modifier.padding(end = 255.dp))
|
||||||
|
TextField(
|
||||||
|
modifier = Modifier.width(350.dp).height(70.dp).padding(bottom = 16.dp),
|
||||||
|
value = codeIn,
|
||||||
|
onValueChange = {onCodeChange(it)}
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(text = "New Password", modifier = Modifier.padding(end = 255.dp))
|
||||||
|
TextField(
|
||||||
|
modifier = Modifier.width(300.dp).height(70.dp).padding(bottom = 16.dp),
|
||||||
|
value = newPassword,
|
||||||
|
onValueChange = {onNewPasswordChange(it)}
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,381 @@
|
|||||||
|
package com.example.testktor.method.main
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
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.aspectRatio
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.offset
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.foundation.lazy.LazyRow
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.foundation.text.ClickableText
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.Add
|
||||||
|
import androidx.compose.material.icons.filled.Favorite
|
||||||
|
import androidx.compose.material.icons.filled.FavoriteBorder
|
||||||
|
import androidx.compose.material.icons.filled.Home
|
||||||
|
import androidx.compose.material.icons.filled.Notifications
|
||||||
|
import androidx.compose.material.icons.filled.Person
|
||||||
|
import androidx.compose.material.icons.filled.Search
|
||||||
|
import androidx.compose.material.icons.filled.ShoppingCart
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.ButtonDefaults
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextField
|
||||||
|
import androidx.compose.material3.TextFieldDefaults
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import coil.compose.AsyncImage
|
||||||
|
import com.example.testktor.Category
|
||||||
|
import com.example.testktor.R
|
||||||
|
import com.example.testktor.Sneaker
|
||||||
|
import com.example.testktor.SneakerShop
|
||||||
|
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
fun TopNavigationBar(){
|
||||||
|
Row (
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(16.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
){
|
||||||
|
IconButton(onClick = { /* TODO: действие кнопки */ }) {
|
||||||
|
Image(
|
||||||
|
painter = painterResource(id = R.drawable.hamburger),
|
||||||
|
contentDescription = "menu",
|
||||||
|
modifier = Modifier.size(40.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.weight(1f),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "Главная",
|
||||||
|
fontSize = 30.sp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
IconButton(onClick = { /* TODO: действие кнопки */ }) {
|
||||||
|
Image(
|
||||||
|
painter = painterResource(id = R.drawable.frame31),
|
||||||
|
contentDescription = "menu",
|
||||||
|
modifier = Modifier.size(40.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun Searchbar(searchBox: String, onSearchChange: (String) -> Unit){
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(16.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
){
|
||||||
|
TextField(
|
||||||
|
modifier = Modifier
|
||||||
|
.width(300.dp)
|
||||||
|
.height(70.dp)
|
||||||
|
.padding(bottom = 16.dp),
|
||||||
|
value = searchBox,
|
||||||
|
onValueChange = { onSearchChange(it) },
|
||||||
|
placeholder = {
|
||||||
|
Text(
|
||||||
|
text = "Поиск",
|
||||||
|
color = Color.Gray,
|
||||||
|
fontSize = 14.sp
|
||||||
|
)
|
||||||
|
},
|
||||||
|
colors = TextFieldDefaults.textFieldColors(
|
||||||
|
containerColor = Color.White,
|
||||||
|
focusedIndicatorColor = Color.Transparent,
|
||||||
|
unfocusedIndicatorColor = Color.Transparent,
|
||||||
|
cursorColor = Color.Black
|
||||||
|
),
|
||||||
|
shape = RoundedCornerShape(12.dp),
|
||||||
|
leadingIcon = {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Search,
|
||||||
|
contentDescription = "Search",
|
||||||
|
tint = Color.Gray
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
IconButton(onClick = { /* TODO: действие кнопки */ }) {
|
||||||
|
Image(
|
||||||
|
painter = painterResource(id = R.drawable.group12),
|
||||||
|
contentDescription = "settings",
|
||||||
|
modifier = Modifier.size(60.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun OverSmth(smth: String){
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(16.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
ClickableText(
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
text = buildAnnotatedString { append(smth) },
|
||||||
|
onClick = {/* TODO: действие кнопки */},
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 16.sp,
|
||||||
|
color = Color.Black
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ClickableText(
|
||||||
|
text = buildAnnotatedString { append("Все") },
|
||||||
|
onClick = {/* TODO: действие кнопки */},
|
||||||
|
style = TextStyle(
|
||||||
|
fontSize = 12.sp,
|
||||||
|
color = Color.Cyan
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
fun SalesBar() {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(16.dp)
|
||||||
|
) {
|
||||||
|
OverSmth("Акции")
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(160.dp)
|
||||||
|
.background(Color(0xFFF7F7F9)),
|
||||||
|
contentAlignment = Alignment.Center,
|
||||||
|
) {
|
||||||
|
Image(
|
||||||
|
painter = painterResource(id = R.drawable.img),
|
||||||
|
contentDescription = "sales",
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
contentScale = ContentScale.Fit
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
fun BottomNavigationBar() {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
contentAlignment = Alignment.BottomCenter
|
||||||
|
) {
|
||||||
|
Image(
|
||||||
|
painter = painterResource(id = R.drawable.bottom),
|
||||||
|
contentDescription = null,
|
||||||
|
contentScale = ContentScale.FillWidth,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.aspectRatio(3f)
|
||||||
|
)
|
||||||
|
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(bottom = 16.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.Center
|
||||||
|
) {
|
||||||
|
IconButton(onClick = { /* TODO: действие кнопки */ }) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Home,
|
||||||
|
contentDescription = "home",
|
||||||
|
modifier = Modifier.size(40.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.width(20.dp))
|
||||||
|
IconButton(onClick = { /* TODO: действие кнопки */ }) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.FavoriteBorder,
|
||||||
|
contentDescription = "favourite",
|
||||||
|
modifier = Modifier.size(40.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.width(20.dp))
|
||||||
|
IconButton(
|
||||||
|
onClick = { /* TODO: действие кнопки */ },
|
||||||
|
modifier = Modifier.offset(y = (-20).dp).size(80.dp)
|
||||||
|
) {
|
||||||
|
Image(
|
||||||
|
painter = painterResource(id = R.drawable.group123),
|
||||||
|
contentDescription = "korzina",
|
||||||
|
modifier = Modifier.size(80.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.width(20.dp))
|
||||||
|
IconButton(onClick = { /* TODO: действие кнопки */ }) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Notifications,
|
||||||
|
contentDescription = "notice",
|
||||||
|
modifier = Modifier.size(40.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.width(20.dp))
|
||||||
|
IconButton(onClick = { /* TODO: действие кнопки */ }) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Person,
|
||||||
|
contentDescription = "profile",
|
||||||
|
modifier = Modifier.size(40.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun CategorySelection(
|
||||||
|
categories: List<Category>,
|
||||||
|
selectedCategory: Category?,
|
||||||
|
onCategorySelected: (Category?) -> Unit
|
||||||
|
) {
|
||||||
|
LazyRow {
|
||||||
|
items(categories) { category ->
|
||||||
|
CategoryButton(
|
||||||
|
category = category,
|
||||||
|
isSelected = category == selectedCategory,
|
||||||
|
onClick = {
|
||||||
|
if (selectedCategory == category) {
|
||||||
|
onCategorySelected(null)
|
||||||
|
} else {
|
||||||
|
onCategorySelected(category)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun CategoryButton(category: Category, isSelected: Boolean, onClick: () -> Unit) {
|
||||||
|
Button(
|
||||||
|
onClick = onClick,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(8.dp),
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
containerColor = if (isSelected) Color.Blue else Color.White
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text(text = category.name, color = Color.Black)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SneakerSelection(sneakers: List<SneakerShop>) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
horizontalArrangement = Arrangement.SpaceEvenly
|
||||||
|
) {
|
||||||
|
sneakers.take(2).forEachIndexed { index ,sneakerShop ->
|
||||||
|
SneakerButton(
|
||||||
|
sneakerShop = sneakerShop,
|
||||||
|
onClick = { /* TODO: Действие кнопки */ },
|
||||||
|
onFavoriteClick = { /* TODO: Действие кнопки */ }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SneakerButton(sneakerShop: SneakerShop, onClick: () -> Unit, onFavoriteClick: () -> Unit) {
|
||||||
|
val cost = "₽${sneakerShop.sneaker.cost}"
|
||||||
|
|
||||||
|
var isLiked by remember { mutableStateOf(false) }
|
||||||
|
var isAddedToCart by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
Box(modifier = Modifier.padding(8.dp)) {
|
||||||
|
Button(
|
||||||
|
onClick = onClick,
|
||||||
|
modifier = Modifier
|
||||||
|
.width(140.dp)
|
||||||
|
.height(180.dp),
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
containerColor = Color.White
|
||||||
|
),
|
||||||
|
shape = RoundedCornerShape(12.dp)
|
||||||
|
) {
|
||||||
|
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
|
AsyncImage(
|
||||||
|
model = sneakerShop.sneaker.photo,
|
||||||
|
contentDescription = "Sneaker Image",
|
||||||
|
modifier = Modifier
|
||||||
|
.width(200.dp)
|
||||||
|
.height(90.dp)
|
||||||
|
)
|
||||||
|
Text(text = sneakerShop.sneaker.name, fontSize = 20.sp, color = Color.DarkGray)
|
||||||
|
Text(text = cost, fontSize = 15.sp, color = Color.Black)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IconButton(
|
||||||
|
onClick = {isLiked = !isLiked},
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.TopStart)
|
||||||
|
.size(28.dp)
|
||||||
|
.padding(4.dp)
|
||||||
|
) {
|
||||||
|
val iconRes = if (sneakerShop.likeOrNot) Icons.Default.Favorite else Icons.Default.FavoriteBorder
|
||||||
|
Icon(imageVector = iconRes, contentDescription = "Favourite", tint = Color.Red)
|
||||||
|
}
|
||||||
|
|
||||||
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
isAddedToCart = !isAddedToCart
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.BottomEnd)
|
||||||
|
.size(32.dp)
|
||||||
|
.padding(4.dp)
|
||||||
|
) {
|
||||||
|
val iconRes = if (isAddedToCart) Icons.Default.ShoppingCart else Icons.Default.Add
|
||||||
|
Icon(imageVector = iconRes, contentDescription = "Favourite", tint = Color.Cyan)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,21 +1,16 @@
|
|||||||
package com.example.testktor.screen.auth
|
package com.example.testktor.screen.auth
|
||||||
|
|
||||||
import androidx.compose.foundation.hoverable
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
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.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.text.ClickableText
|
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextField
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@ -23,15 +18,16 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
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.text.input.PasswordVisualTransformation
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.buildAnnotatedString
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.example.testktor.authUser
|
import com.example.testktor.authUser
|
||||||
|
import com.example.testktor.method.auth.BotBar
|
||||||
|
import com.example.testktor.method.auth.ButtonBack
|
||||||
|
import com.example.testktor.method.auth.Restore
|
||||||
|
import com.example.testktor.method.auth.TopBar
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import io.ktor.client.engine.android.Android
|
import io.ktor.client.engine.android.Android
|
||||||
|
|
||||||
@ -72,17 +68,12 @@ fun AuthContent(
|
|||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
verticalArrangement = Arrangement.Center
|
verticalArrangement = Arrangement.Center
|
||||||
) {
|
) {
|
||||||
// Отображение текста "Success" в левом верхнем углу
|
ButtonBack(navController)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(140.dp))
|
||||||
|
|
||||||
if (authSuccess != null){
|
if (authSuccess != null){
|
||||||
if (authSuccess == "Success") {
|
if (authSuccess == "Success") {
|
||||||
// Text(
|
|
||||||
// text = "Success",
|
|
||||||
// modifier = Modifier
|
|
||||||
// .padding(start = 16.dp, top = 16.dp)
|
|
||||||
// .align(Alignment.Start),
|
|
||||||
// color = Color.Green,
|
|
||||||
// style = TextStyle(fontSize = 18.sp, fontWeight = FontWeight.Bold)
|
|
||||||
// )
|
|
||||||
navController.navigate("mainSneakers_screen")
|
navController.navigate("mainSneakers_screen")
|
||||||
} else{
|
} else{
|
||||||
Text(
|
Text(
|
||||||
@ -96,36 +87,8 @@ fun AuthContent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Text(
|
TopBar(emailIn, {emailIn = it}, passwordIn, {passwordIn = it})
|
||||||
text = "Привет!",
|
Restore(navController)
|
||||||
style = TextStyle(fontSize = 32.sp, fontWeight = FontWeight.Bold),
|
|
||||||
modifier = Modifier.height(60.dp).padding(bottom = 20.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = "Заполните Свои данные или продолжите через социальные медиа",
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(bottom = 20.dp),
|
|
||||||
style = TextStyle(fontSize = 16.sp),
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
maxLines = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(text = "Email", modifier = Modifier.padding(end = 255.dp))
|
|
||||||
TextField(
|
|
||||||
modifier = Modifier.width(300.dp).height(70.dp).padding(bottom = 16.dp),
|
|
||||||
value = emailIn,
|
|
||||||
onValueChange = { emailIn = it }
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(text = "Password", modifier = Modifier.padding(end = 225.dp))
|
|
||||||
TextField(
|
|
||||||
modifier = Modifier.width(300.dp).height(70.dp).padding(bottom = 16.dp),
|
|
||||||
value = passwordIn,
|
|
||||||
onValueChange = { passwordIn = it },
|
|
||||||
visualTransformation = PasswordVisualTransformation()
|
|
||||||
)
|
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier.width(350.dp).height(50.dp),
|
modifier = Modifier.width(350.dp).height(50.dp),
|
||||||
@ -138,45 +101,6 @@ fun AuthContent(
|
|||||||
Text("Войти")
|
Text("Войти")
|
||||||
}
|
}
|
||||||
|
|
||||||
Row(
|
BotBar(navController)
|
||||||
modifier = Modifier
|
|
||||||
.padding(top = 16.dp)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
horizontalArrangement = Arrangement.Center
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = "Вы впервые? ",
|
|
||||||
style = TextStyle(fontSize = 16.sp, color = Color.Black)
|
|
||||||
)
|
|
||||||
|
|
||||||
ClickableText(
|
|
||||||
text = buildAnnotatedString { append("Создать пользователя") },
|
|
||||||
onClick = {
|
|
||||||
navController.navigate("registration_screen")
|
|
||||||
},
|
|
||||||
style = TextStyle(
|
|
||||||
fontSize = 16.sp,
|
|
||||||
color = Color.Black
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(top = 8.dp)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
horizontalArrangement = Arrangement.Center
|
|
||||||
) {
|
|
||||||
ClickableText(
|
|
||||||
text = buildAnnotatedString { append("Восстановить") },
|
|
||||||
onClick = {
|
|
||||||
navController.navigate("forgotPassword_screen")
|
|
||||||
},
|
|
||||||
style = TextStyle(
|
|
||||||
fontSize = 16.sp,
|
|
||||||
color = Color.LightGray
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,19 +1,13 @@
|
|||||||
package com.example.matuletest.ui.auth
|
package com.example.matuletest.ui.auth
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.foundation.layout.width
|
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.Slider
|
|
||||||
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.LaunchedEffect
|
||||||
@ -24,17 +18,11 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.graphics.Brush
|
import androidx.compose.ui.graphics.Brush
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.res.painterResource
|
|
||||||
import androidx.compose.ui.text.font.FontStyle
|
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.text.style.LineHeightStyle
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
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 com.example.testktor.R
|
import com.example.testktor.R
|
||||||
import io.ktor.websocket.Frame
|
import com.example.testktor.method.auth.Sliderik
|
||||||
import java.lang.reflect.Modifier
|
import com.example.testktor.method.auth.Textik
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun FirstScreen(onNavigateToSliderScreen: () -> Unit) {
|
fun FirstScreen(onNavigateToSliderScreen: () -> Unit) {
|
||||||
@ -78,52 +66,11 @@ fun SliderScreen(onNavigateToAuthScreen: () -> Unit) {
|
|||||||
.background(Brush.horizontalGradient(listOf(Color(0xFF48B2E7), Color(0xFF0076B1)))),
|
.background(Brush.horizontalGradient(listOf(Color(0xFF48B2E7), Color(0xFF0076B1)))),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
) {
|
) {
|
||||||
Image(
|
Textik(imageId, textList, textList2, currentIndex)
|
||||||
painter = painterResource(id = imageId),
|
|
||||||
contentDescription = "Изображение",
|
|
||||||
modifier = androidx.compose.ui.Modifier.width(670.dp).height(600.dp).padding(start = 20.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(
|
|
||||||
color = Color.White,
|
|
||||||
fontStyle = FontStyle.Italic,
|
|
||||||
text = textList[currentIndex],
|
|
||||||
fontSize = 24.sp,
|
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
modifier = androidx.compose.ui.Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(top = 40.dp)
|
|
||||||
.width(700.dp).height(30.dp)
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
color = Color.White,
|
|
||||||
fontStyle = FontStyle.Italic,
|
|
||||||
text = textList2[currentIndex],
|
|
||||||
fontSize = 18.sp,
|
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
modifier = androidx.compose.ui.Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(top = 40.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer(modifier = androidx.compose.ui.Modifier.weight(1f))
|
Spacer(modifier = androidx.compose.ui.Modifier.weight(1f))
|
||||||
|
|
||||||
Slider(
|
Sliderik(sliderValue, maxIndex){ newValue -> sliderValue = newValue }
|
||||||
value = sliderValue,
|
|
||||||
onValueChange = { newValue -> sliderValue = newValue },
|
|
||||||
valueRange = 0f..maxIndex.toFloat(),
|
|
||||||
steps = maxIndex - 1,
|
|
||||||
colors = androidx.compose.material3.SliderDefaults.colors(
|
|
||||||
thumbColor = Color.White,
|
|
||||||
activeTrackColor = Color(0xFF0076B1),
|
|
||||||
inactiveTrackColor = Color(0xFFB0B0B0)
|
|
||||||
),
|
|
||||||
modifier = androidx.compose.ui.Modifier.fillMaxWidth()
|
|
||||||
)
|
|
||||||
|
|
||||||
// Spacer(modifier = androidx.compose.ui.Modifier.height(20.dp))
|
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
|
@ -30,6 +30,7 @@ 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.forgotPassword
|
import com.example.testktor.forgotPassword
|
||||||
|
import com.example.testktor.method.auth.BarForgot
|
||||||
import com.example.testktor.resetPassword
|
import com.example.testktor.resetPassword
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import io.ktor.client.engine.android.Android
|
import io.ktor.client.engine.android.Android
|
||||||
@ -67,7 +68,6 @@ fun ForgotPasswordContent(
|
|||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
verticalArrangement = Arrangement.Center
|
verticalArrangement = Arrangement.Center
|
||||||
) {
|
) {
|
||||||
// Отображение текста "Success" в левом верхнем углу
|
|
||||||
if (forgotSuccess != null){
|
if (forgotSuccess != null){
|
||||||
if (forgotSuccess == "Success") {
|
if (forgotSuccess == "Success") {
|
||||||
navController.navigate("resetPassword_screen")
|
navController.navigate("resetPassword_screen")
|
||||||
@ -83,28 +83,7 @@ fun ForgotPasswordContent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Text(
|
BarForgot(emailIn){emailIn = it}
|
||||||
text = "Забыл Пароль",
|
|
||||||
style = TextStyle(fontSize = 32.sp, fontWeight = FontWeight.Bold),
|
|
||||||
modifier = Modifier.height(60.dp).padding(bottom = 20.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = "Введите свою учетную запись для сброса",
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(bottom = 20.dp),
|
|
||||||
style = TextStyle(fontSize = 16.sp),
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
maxLines = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(text = "Email", modifier = Modifier.padding(end = 255.dp))
|
|
||||||
TextField(
|
|
||||||
modifier = Modifier.width(300.dp).height(70.dp).padding(bottom = 16.dp),
|
|
||||||
value = emailIn,
|
|
||||||
onValueChange = { emailIn = it }
|
|
||||||
)
|
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier.width(350.dp).height(50.dp),
|
modifier = Modifier.width(350.dp).height(50.dp),
|
||||||
|
@ -1,63 +0,0 @@
|
|||||||
package com.example.testktor.screen.auth
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.items
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.compose.ui.unit.sp
|
|
||||||
import androidx.navigation.NavController
|
|
||||||
import com.example.testktor.Sneaker
|
|
||||||
import com.example.testktor.authUser
|
|
||||||
import com.example.testktor.getSneakers
|
|
||||||
import io.ktor.client.HttpClient
|
|
||||||
import io.ktor.client.engine.android.Android
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun MainSneakersScreen(navController: NavController) {
|
|
||||||
var sneakers by remember { mutableStateOf<List<Sneaker>>(emptyList()) }
|
|
||||||
val coroutineScope = rememberCoroutineScope()
|
|
||||||
|
|
||||||
val client = HttpClient(Android)
|
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
coroutineScope.launch {
|
|
||||||
sneakers = getSneakers(client)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SneakersContent(sneakers)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SneakersContent(
|
|
||||||
sneakers: List<Sneaker>
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.padding(16.dp),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
|
||||||
) {
|
|
||||||
Text(text = "Список кроссовок", fontSize = 24.sp, modifier = Modifier.padding(bottom = 16.dp))
|
|
||||||
|
|
||||||
LazyColumn(modifier = Modifier.fillMaxWidth()) {
|
|
||||||
items(sneakers) { sneaker ->
|
|
||||||
Text(text = sneaker.name, fontSize = 18.sp, modifier = Modifier.padding(8.dp))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,19 +2,15 @@ package com.example.testktor.screen.auth
|
|||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
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.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.text.ClickableText
|
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextField
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@ -23,15 +19,12 @@ import androidx.compose.ui.Alignment
|
|||||||
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.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.buildAnnotatedString
|
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
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.lifecycle.viewmodel.compose.viewModel
|
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.example.testktor.authUser
|
import com.example.testktor.method.auth.BotBarReg
|
||||||
|
import com.example.testktor.method.auth.TopBarReg
|
||||||
import com.example.testktor.regUser
|
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
|
||||||
@ -77,17 +70,9 @@ fun RegContent(
|
|||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
verticalArrangement = Arrangement.Center
|
verticalArrangement = Arrangement.Center
|
||||||
) {
|
) {
|
||||||
// Отображение текста "Success" в левом верхнем углу
|
|
||||||
if (regSuccess != null){
|
if (regSuccess != null){
|
||||||
if (regSuccess == "Success") {
|
if (regSuccess == "Success") {
|
||||||
Text(
|
navController.navigate("auth_screen")
|
||||||
text = "Success",
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(start = 16.dp, top = 16.dp)
|
|
||||||
.align(Alignment.Start),
|
|
||||||
color = Color.Green,
|
|
||||||
style = TextStyle(fontSize = 18.sp, fontWeight = FontWeight.Bold)
|
|
||||||
)
|
|
||||||
} else{
|
} else{
|
||||||
Text(
|
Text(
|
||||||
text = "Error",
|
text = "Error",
|
||||||
@ -100,42 +85,9 @@ fun RegContent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Text(
|
Spacer(modifier = Modifier.height(140.dp))
|
||||||
text = "Регистрация!",
|
|
||||||
style = TextStyle(fontSize = 32.sp, fontWeight = FontWeight.Bold),
|
|
||||||
modifier = Modifier.height(60.dp).padding(bottom = 20.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(
|
TopBarReg(nameIn, {nameIn = it}, emailIn, {emailIn = it}, passwordIn, {passwordIn = it})
|
||||||
text = "Заполните Свои данные или продолжите через социальные медиа",
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(bottom = 20.dp),
|
|
||||||
style = TextStyle(fontSize = 16.sp),
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
maxLines = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(text = "Ваше имя", modifier = Modifier.padding(end = 255.dp))
|
|
||||||
TextField(
|
|
||||||
modifier = Modifier.width(300.dp).height(70.dp).padding(bottom = 16.dp),
|
|
||||||
value = nameIn,
|
|
||||||
onValueChange = { nameIn = it }
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(text = "Email", modifier = Modifier.padding(end = 255.dp))
|
|
||||||
TextField(
|
|
||||||
modifier = Modifier.width(300.dp).height(70.dp).padding(bottom = 16.dp),
|
|
||||||
value = emailIn,
|
|
||||||
onValueChange = { emailIn = it }
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(text = "Password", modifier = Modifier.padding(end = 225.dp))
|
|
||||||
TextField(
|
|
||||||
modifier = Modifier.width(300.dp).height(70.dp).padding(bottom = 16.dp),
|
|
||||||
value = passwordIn,
|
|
||||||
onValueChange = { passwordIn = it }
|
|
||||||
)
|
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier.width(350.dp).height(50.dp),
|
modifier = Modifier.width(350.dp).height(50.dp),
|
||||||
@ -148,120 +100,8 @@ fun RegContent(
|
|||||||
Text("Зарегистрироваться")
|
Text("Зарегистрироваться")
|
||||||
}
|
}
|
||||||
|
|
||||||
Row(
|
Spacer(modifier = Modifier.height(140.dp))
|
||||||
modifier = Modifier
|
|
||||||
.padding(top = 16.dp)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
horizontalArrangement = Arrangement.Center
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = "Есть аккаунт? ",
|
|
||||||
style = TextStyle(fontSize = 16.sp, color = Color.Black)
|
|
||||||
)
|
|
||||||
|
|
||||||
ClickableText(
|
BotBarReg(navController)
|
||||||
text = buildAnnotatedString { append("Войти") },
|
|
||||||
onClick = {
|
|
||||||
navController.navigate("auth_screen")
|
|
||||||
},
|
|
||||||
style = TextStyle(
|
|
||||||
fontSize = 16.sp,
|
|
||||||
color = Color.Black
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//@Composable
|
|
||||||
//fun RegistrationContent(viewModel: AuthScreenViewModel, navController: NavController){
|
|
||||||
// val regState = viewModel.registrationScreenState.collectAsState()
|
|
||||||
//
|
|
||||||
// if (regState.value.isSignUp) {
|
|
||||||
// Text("Success Registration")
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Column(
|
|
||||||
// modifier = Modifier.fillMaxSize(),
|
|
||||||
// horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
// verticalArrangement = Arrangement.Center
|
|
||||||
// ) {
|
|
||||||
// Text(
|
|
||||||
// text = "Регистрация!",
|
|
||||||
// style = TextStyle(fontSize = 32.sp, fontWeight = FontWeight.Bold),
|
|
||||||
// modifier = Modifier.height(60.dp).padding(bottom = 20.dp)
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// Text(
|
|
||||||
// text = "Заполните Свои данные или продолжите через социальные медиа",
|
|
||||||
// modifier = Modifier
|
|
||||||
// .fillMaxWidth()
|
|
||||||
// .padding(bottom = 20.dp),
|
|
||||||
// style = TextStyle(fontSize = 16.sp),
|
|
||||||
// textAlign = TextAlign.Center,
|
|
||||||
// maxLines = 2
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
//// Text(text = "Ваше имя", modifier = Modifier.padding(end = 255.dp))
|
|
||||||
//// TextField(
|
|
||||||
//// modifier = Modifier.width(300.dp).height(70.dp).padding(bottom = 16.dp),
|
|
||||||
//// value = regState.value.email,
|
|
||||||
//// onValueChange = {
|
|
||||||
//// viewModel.setEmail(it)
|
|
||||||
//// })
|
|
||||||
//
|
|
||||||
// Text(text = "Email", modifier = Modifier.padding(end = 255.dp))
|
|
||||||
// TextField(
|
|
||||||
// modifier = Modifier.width(300.dp).height(70.dp).padding(bottom = 16.dp),
|
|
||||||
// value = regState.value.email,
|
|
||||||
// onValueChange = {
|
|
||||||
// viewModel.setEmail(it, true)
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// Text(text = "Password", modifier = Modifier.padding(end = 225.dp))
|
|
||||||
// TextField(
|
|
||||||
// modifier = Modifier.width(300.dp).height(70.dp).padding(bottom = 16.dp),
|
|
||||||
// value = regState.value.password,
|
|
||||||
// onValueChange = {
|
|
||||||
// viewModel.setPassword(it, true)
|
|
||||||
// },
|
|
||||||
// visualTransformation = PasswordVisualTransformation()
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// Button(
|
|
||||||
// modifier = Modifier.width(350.dp).height(50.dp),
|
|
||||||
// colors = androidx.compose.material3.ButtonDefaults.buttonColors(
|
|
||||||
// containerColor = Color(0xFF48B2E7),
|
|
||||||
// contentColor = Color.White
|
|
||||||
// ),
|
|
||||||
// onClick = {
|
|
||||||
// viewModel.reg()
|
|
||||||
// }) {
|
|
||||||
// Text("Зарегестрироваться")
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Row(
|
|
||||||
// modifier = Modifier
|
|
||||||
// .padding(top = 16.dp)
|
|
||||||
// .fillMaxWidth(),
|
|
||||||
// horizontalArrangement = Arrangement.Center
|
|
||||||
// ) {
|
|
||||||
// Text(
|
|
||||||
// text = "Есть аккаунт? ",
|
|
||||||
// style = TextStyle(fontSize = 16.sp, color = Color.Black)
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// ClickableText(
|
|
||||||
// text = buildAnnotatedString { append("Войти") },
|
|
||||||
// onClick = {
|
|
||||||
// navController.navigate("auth_screen")
|
|
||||||
// },
|
|
||||||
// style = TextStyle(
|
|
||||||
// fontSize = 16.sp,
|
|
||||||
// color = Color.Black
|
|
||||||
// ),
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
@ -25,7 +25,10 @@ import androidx.compose.ui.text.style.TextAlign
|
|||||||
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.android.identity.cbor.Uint
|
||||||
import com.example.testktor.authUser
|
import com.example.testktor.authUser
|
||||||
|
import com.example.testktor.method.auth.TextFieldsReset
|
||||||
|
import com.example.testktor.method.auth.TopBarReset
|
||||||
import com.example.testktor.resetPassword
|
import com.example.testktor.resetPassword
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import io.ktor.client.engine.android.Android
|
import io.ktor.client.engine.android.Android
|
||||||
@ -67,17 +70,9 @@ fun ResetPasswordContent(
|
|||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
verticalArrangement = Arrangement.Center
|
verticalArrangement = Arrangement.Center
|
||||||
) {
|
) {
|
||||||
// Отображение текста "Success" в левом верхнем углу
|
|
||||||
if (resetSuccess != null){
|
if (resetSuccess != null){
|
||||||
if (resetSuccess == "Success") {
|
if (resetSuccess == "Success") {
|
||||||
Text(
|
navController.navigate("auth_screen")
|
||||||
text = "Success",
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(start = 16.dp, top = 16.dp)
|
|
||||||
.align(Alignment.Start),
|
|
||||||
color = Color.Green,
|
|
||||||
style = TextStyle(fontSize = 18.sp, fontWeight = FontWeight.Bold)
|
|
||||||
)
|
|
||||||
} else{
|
} else{
|
||||||
Text(
|
Text(
|
||||||
text = "Error",
|
text = "Error",
|
||||||
@ -90,35 +85,8 @@ fun ResetPasswordContent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Text(
|
TopBarReset()
|
||||||
text = "ОТР Проверка",
|
TextFieldsReset(codeIn, {codeIn = it}, newPasswordIn, {newPasswordIn = it})
|
||||||
style = TextStyle(fontSize = 32.sp, fontWeight = FontWeight.Bold),
|
|
||||||
modifier = Modifier.height(60.dp).padding(bottom = 20.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = "Пожалуйста, проверьте свою электронную почту, чтобы увидеть код подтверждения",
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(bottom = 20.dp),
|
|
||||||
style = TextStyle(fontSize = 16.sp),
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
maxLines = 3
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(text = "OTP Code", modifier = Modifier.padding(end = 255.dp))
|
|
||||||
TextField(
|
|
||||||
modifier = Modifier.width(300.dp).height(70.dp).padding(bottom = 16.dp),
|
|
||||||
value = codeIn,
|
|
||||||
onValueChange = { codeIn = it }
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(text = "New Password", modifier = Modifier.padding(end = 255.dp))
|
|
||||||
TextField(
|
|
||||||
modifier = Modifier.width(300.dp).height(70.dp).padding(bottom = 16.dp),
|
|
||||||
value = newPasswordIn,
|
|
||||||
onValueChange = { newPasswordIn = it }
|
|
||||||
)
|
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier.width(350.dp).height(50.dp),
|
modifier = Modifier.width(350.dp).height(50.dp),
|
||||||
|
@ -0,0 +1,99 @@
|
|||||||
|
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.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.derivedStateOf
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
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.Category
|
||||||
|
import com.example.testktor.Sneaker
|
||||||
|
import com.example.testktor.SneakerCategoryResponse
|
||||||
|
import com.example.testktor.SneakerShop
|
||||||
|
import com.example.testktor.getSneakers
|
||||||
|
import com.example.testktor.method.main.BottomNavigationBar
|
||||||
|
import com.example.testktor.method.main.CategorySelection
|
||||||
|
import com.example.testktor.method.main.OverSmth
|
||||||
|
import com.example.testktor.method.main.SalesBar
|
||||||
|
import com.example.testktor.method.main.Searchbar
|
||||||
|
import com.example.testktor.method.main.SneakerSelection
|
||||||
|
import com.example.testktor.method.main.TopNavigationBar
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.client.engine.android.Android
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun MainSneakersScreen(navController: NavController) {
|
||||||
|
val searchBox by remember { mutableStateOf("") }
|
||||||
|
var sneakersCategories by remember { mutableStateOf(SneakerCategoryResponse(emptyList(), emptyList())) }
|
||||||
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
val client = remember { HttpClient(Android) }
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
sneakersCategories = getSneakers(client) ?: SneakerCategoryResponse(emptyList(), emptyList())
|
||||||
|
}
|
||||||
|
|
||||||
|
Box(modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(Color(0xFFF7F7F9))) {
|
||||||
|
SneakersContent(sneakersCategories, searchBox)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SneakersContent(
|
||||||
|
sneakersCategories: SneakerCategoryResponse,
|
||||||
|
searchBox: String
|
||||||
|
) {
|
||||||
|
var searchBoxIn by remember { mutableStateOf(searchBox) }
|
||||||
|
var selectedCategory by remember { mutableStateOf<Category?>(null) }
|
||||||
|
var sneakers by remember(selectedCategory) {
|
||||||
|
mutableStateOf(
|
||||||
|
sneakersCategories.sneakers.filter {
|
||||||
|
selectedCategory == null || it.categoryId == selectedCategory?.id
|
||||||
|
}.map {
|
||||||
|
sneaker -> SneakerShop(sneaker, false)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(16.dp),
|
||||||
|
)
|
||||||
|
{
|
||||||
|
TopNavigationBar()
|
||||||
|
Searchbar(searchBoxIn, {searchBoxIn = it})
|
||||||
|
|
||||||
|
|
||||||
|
Column {
|
||||||
|
Text(text = "Категории", fontSize = 16.sp)
|
||||||
|
|
||||||
|
CategorySelection(
|
||||||
|
categories = sneakersCategories.categories,
|
||||||
|
selectedCategory = selectedCategory,
|
||||||
|
onCategorySelected = { selectedCategory = it }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
OverSmth("Популярное")
|
||||||
|
SneakerSelection(sneakers = sneakers)
|
||||||
|
SalesBar()
|
||||||
|
BottomNavigationBar()
|
||||||
|
}
|
||||||
|
}
|
BIN
app/src/main/res/drawable/add_sneaker.png
Normal file
After Width: | Height: | Size: 835 B |
BIN
app/src/main/res/drawable/bottom.png
Normal file
After Width: | Height: | Size: 9.9 KiB |
BIN
app/src/main/res/drawable/buy_sneaker.png
Normal file
After Width: | Height: | Size: 608 B |
BIN
app/src/main/res/drawable/frame.png
Normal file
After Width: | Height: | Size: 699 B |
BIN
app/src/main/res/drawable/frame31.png
Normal file
After Width: | Height: | Size: 937 B |
BIN
app/src/main/res/drawable/group12.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
app/src/main/res/drawable/group123.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
app/src/main/res/drawable/hamburger.png
Normal file
After Width: | Height: | Size: 191 B |
BIN
app/src/main/res/drawable/heart.png
Normal file
After Width: | Height: | Size: 650 B |
BIN
app/src/main/res/drawable/heart_sneaker.png
Normal file
After Width: | Height: | Size: 715 B |
BIN
app/src/main/res/drawable/home.png
Normal file
After Width: | Height: | Size: 553 B |
BIN
app/src/main/res/drawable/icon.png
Normal file
After Width: | Height: | Size: 631 B |
BIN
app/src/main/res/drawable/img.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
app/src/main/res/drawable/img_1.png
Normal file
After Width: | Height: | Size: 44 KiB |