Explorar o código

addingTheFunctionOfCreatingAnOrderForClothesWithACustomPrint

x1tosi hai 4 días
pai
achega
26cb9641b2
Modificáronse 15 ficheiros con 636 adicións e 204 borrados
  1. 1 0
      ProjectInAndroidStudio/app/build.gradle.kts
  2. 22 5
      ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/MainActivity.kt
  3. 125 13
      ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/MainViewModel.kt
  4. 25 0
      ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/Models/custom_clothes_orders.kt
  5. 23 0
      ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/Models/custom_prints.kt
  6. 2 10
      ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/Models/order_items.kt
  7. 3 5
      ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/Models/ready_made_clothes_orders.kt
  8. 40 19
      ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/Screens/CartScreen.kt
  9. 13 7
      ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/Screens/MainScreen.kt
  10. 15 6
      ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/Screens/ThxForPaymentScreen.kt
  11. 315 107
      ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/Screens/printWorkshopScreen.kt
  12. 17 14
      ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/Screens/templateSelectionScreen.kt
  13. 33 18
      ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/Screens/userProfileScreen.kt
  14. 2 0
      ProjectInAndroidStudio/gradle/libs.versions.toml
  15. BIN=BIN
      Скриншоты дизайна/Страницы создания принта на одежде.png

+ 1 - 0
ProjectInAndroidStudio/app/build.gradle.kts

@@ -66,6 +66,7 @@ dependencies {
     implementation(libs.androidx.navigation.runtime.ktx)
     implementation(libs.androidx.navigation.compose)
     implementation(libs.firebase.firestore.ktx)
+    implementation(libs.firebase.crashlytics.buildtools)
     testImplementation(libs.junit)
     androidTestImplementation(libs.androidx.junit)
     androidTestImplementation(libs.androidx.espresso.core)

+ 22 - 5
ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/MainActivity.kt

@@ -41,10 +41,18 @@ class MainActivity : ComponentActivity() {
                     composable("load_screen") {
                         LoadScreen(navController)
                     }
-                    composable("print_workshop_screen/{imageUrl}") { backStackEntry ->
-                        val imageUrl = backStackEntry.arguments?.getString("imageUrl")
-                        PrintWorkshopScreen(navController, imageUrl, viewModel = viewModel)
+                    composable(
+                        route = "print_workshop_screen/{id}/{imageUrl}",
+                        arguments = listOf(
+                            navArgument("id") { type = NavType.IntType }, // id как Int
+                            navArgument("imageUrl") { type = NavType.StringType } // imageUrl как String
+                        )
+                    ) { backStackEntry ->
+                        val id = backStackEntry.arguments?.getInt("id") // Извлекаем id как Int
+                        val imageUrl = backStackEntry.arguments?.getString("imageUrl") // Извлекаем imageUrl как String
+                        PrintWorkshopScreen(navController, id, imageUrl, viewModel = viewModel)
                     }
+
                     composable("auth_screen") {
                         AuthScreen(navController)
                     }
@@ -86,6 +94,17 @@ class MainActivity : ComponentActivity() {
 //                        CartScreen(navController, cartProductList = cartProducts, viewModel = viewModel, productId = productId)
 //
 //
+//                    }
+//                    composable(
+//                        "cart_screen", // Убираем обязательный параметр "id"
+//                    ) { backStackEntry ->
+//                        // Параметр id больше не передается, так что можно просто вызвать CartScreen
+//                        CartScreen(
+//                            navController = navController,
+//                            productId = null, // Нет id, можно передать null
+//                            viewModel = viewModel,
+//                            cartProductList = cartProducts
+//                        )
 //                    }
                     composable(
                         "cart_screen/{id}",
@@ -100,8 +119,6 @@ class MainActivity : ComponentActivity() {
                             cartProductList = cartProducts
                         )
                     }
-
-
                     composable("thx_for_payment_screen") {
                         ThxForPaymentScreen(navController, viewModel = viewModel)
                     }

+ 125 - 13
ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/MainViewModel.kt

@@ -1,5 +1,6 @@
 package com.example.uniqwearappproj
 
+import android.graphics.Bitmap
 import android.util.Log
 import androidx.compose.runtime.State
 import androidx.compose.runtime.getValue
@@ -10,24 +11,31 @@ import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
 import com.example.uniqwearappproj.Domain.Constants
-import com.example.uniqwearappproj.Models.orders
+import com.example.uniqwearappproj.Models.clothing_types
+import com.example.uniqwearappproj.Models.custom_clothes_orders
+import com.example.uniqwearappproj.Models.ready_made_clothes_orders
 import com.example.uniqwearappproj.Models.users
+import com.google.firebase.crashlytics.buildtools.reloc.org.apache.commons.io.output.ByteArrayOutputStream
 import io.github.jan.supabase.auth.auth
 import io.github.jan.supabase.auth.providers.builtin.Email
 import io.github.jan.supabase.postgrest.from
 import io.github.jan.supabase.storage.storage
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.launch
 import java.text.SimpleDateFormat
 import java.util.Date
 import java.util.Locale
 
-class MainViewModel: ViewModel()  {
+class MainViewModel : ViewModel() {
     //переменная для результата входа и регистрации
     var authResult = mutableStateOf("")
+
     //uid текущего пользователя
     var currentUserUid = mutableStateOf<String?>(null)
 
     var profileCreated = mutableStateOf(false)
+
     //Для Storage
     val basket = Constants.supabase.storage["pic"]
 
@@ -42,7 +50,6 @@ class MainViewModel: ViewModel()  {
     val user: State<List<users>> = _user
 
 
-
     fun onSignInEmailPassword(emailUser: String, passwordUser: String) {
         viewModelScope.launch {
             try {
@@ -112,13 +119,11 @@ class MainViewModel: ViewModel()  {
     }
 
 
-
-
     //Код для получения данных о конкретном пользователе
     fun selectProfile() {
         viewModelScope.launch {
             try {
-                _user.value =  Constants.supabase.from("users").select {
+                _user.value = Constants.supabase.from("users").select {
                     filter {
                         users::uid eq Constants.supabase.auth.currentUserOrNull()!!.id
                     }
@@ -174,7 +179,7 @@ class MainViewModel: ViewModel()  {
         viewModelScope.launch {
             try {
                 val basket = Constants.supabase.storage["pic"]
-                if(byteArray.isNotEmpty()){
+                if (byteArray.isNotEmpty()) {
                     try {
                         basket.upload(
                             "${Constants.supabase.auth.currentUserOrNull()!!.email}.jpg",
@@ -191,7 +196,7 @@ class MainViewModel: ViewModel()  {
                                 users::uid eq Constants.supabase.auth.currentUserOrNull()!!.id
                             }
                         }
-                    }catch (e: Exception){
+                    } catch (e: Exception) {
                         basket.update(
                             "${Constants.supabase.auth.currentUserOrNull()!!.email}.jpg",
                             byteArray,
@@ -342,8 +347,6 @@ class MainViewModel: ViewModel()  {
     }
 
 
-
-
     fun addOrder(
         totalPrice: Float,
         CountItem: String,
@@ -368,8 +371,8 @@ class MainViewModel: ViewModel()  {
                     // Проверяем, что значения valid
                     if (userIdFromDb != null && ReadyMadeId != null && CountItem.isNotEmpty() && SizeItem.isNotEmpty()) {
                         // Вставка в таблицу "orders"
-                        Constants.supabase.from("orders").insert(
-                            orders(
+                        Constants.supabase.from("ready_made_clothes_orders").insert(
+                            ready_made_clothes_orders(
                                 user_id = userIdFromDb,  // Используем полученный user_id
                                 total_price = totalPrice,
                                 status = "принят",  // Здесь всегда будет "принят"
@@ -397,7 +400,6 @@ class MainViewModel: ViewModel()  {
     }
 
 
-
     //    fun addOrderItems(
 //        orderId: Int,
 //        readyMadeClothesIdItem: Int,
@@ -426,9 +428,119 @@ class MainViewModel: ViewModel()  {
 //        }
 //    }
 //
+    //Функция для получения текущего времени
     fun getCurrentDate(): String {
         // Return current date in string format (adjust according to your needs)
         val sdf = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
         return sdf.format(Date())
     }
+
+
+    // StateFlow для хранения данных о типе одежды
+    private val _clothingType = MutableStateFlow<clothing_types?>(null)
+    val clothingType: StateFlow<clothing_types?> = _clothingType
+
+    private val _isLoading = MutableStateFlow(false)
+    val isLoading: StateFlow<Boolean> = _isLoading
+
+    // Функция для получения данных о типе одежды по id
+    fun fetchClothesTypeById(idClothesType: Int) {
+        viewModelScope.launch {
+            _isLoading.value = true
+            try {
+                // Запрос к Supabase для получения данных из таблицы clothing_types
+                val response = Constants.supabase.from("clothing_types")
+                    .select {
+                        filter {
+                            clothing_types::id eq idClothesType
+                        }
+                    }
+                _clothingType.value = response.decodeSingle<clothing_types>()
+            } catch (e: Exception) {
+                e.printStackTrace()
+                _clothingType.value = null // Если произошла ошибка
+            } finally {
+                _isLoading.value = false
+            }
+        }
+    }
+
+
+    fun saveCanvasDrawingAsAvatar(
+        drawingBitmap: Bitmap,
+        totalPrice: Float,
+        selectedSize: String,
+        quantity: String
+    ) {
+        viewModelScope.launch {
+            try {
+                // Получаем текущий UID пользователя
+                val userUid = Constants.supabase.auth.currentUserOrNull()?.id
+
+                if (userUid != null) {
+                    // Получаем пользователя по UID из таблицы "users"
+                    val userResponse = Constants.supabase.from("users").select {
+                        filter {
+                            users::uid eq userUid // Сравниваем с userUid
+                        }
+                    }.decodeList<users>()
+
+                    val bucket = Constants.supabase.storage["pic"]
+
+                    val userIdFromDb = userResponse.lastOrNull()?.id // Получаем ID пользователя из ответа базы данных
+
+                    // Проверка, что у пользователя есть ID из базы данных
+                    if (userIdFromDb != null) {
+                        // Сохраняем изображение в bucket
+                        val byteArrayOutputStream = ByteArrayOutputStream()
+                        drawingBitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream)
+                        val byteArray = byteArrayOutputStream.toByteArray()
+
+                        // Имя файла будет соответствовать ID пользователя
+                        val fileName = "$userIdFromDb.jpg"
+
+                        try {
+                            bucket.upload(
+                                fileName,
+                                byteArray,
+                                options = { }
+                            )
+                        } catch (e: Exception) {
+                            // Если файл существует, обновляем его
+                            bucket.update(
+                                fileName,
+                                byteArray,
+                                options = { }
+                            )
+                        }
+
+                        // Получаем публичный URL файла
+                        val photoUrl = bucket.publicUrl(fileName)
+
+                        // Создаем объект custom_clothes
+                        val customClothesData = custom_clothes_orders(
+                            price = totalPrice,              // Записываем цену
+                            created_at = getCurrentDate(),  // Используем текущее время для created_at
+                            clothing_type_id = 1,            // Здесь укажите соответствующий ID clothing_type (если нужно)
+                            print_photo_url = photoUrl,      // Записываем URL изображения
+                            user_id = userIdFromDb,          // Записываем user_id
+                            size = selectedSize,             // Записываем размер
+                            count = quantity                 // Записываем количество
+                        )
+
+                        // Обновляем или добавляем данные в таблицу custom_clothes
+                        Constants.supabase.from("custom_clothes_orders").upsert(customClothesData)
+
+                        Log.d("my_tag", "Photo and custom clothing data saved successfully.")
+                    }
+                } else {
+                    Log.d("my_tag", "Ошибка: currentUserUid не задан.")
+                }
+            } catch (e: Exception) {
+                Log.d("my_tag", "Error saving avatar and custom clothes: ${e.message}")
+            }
+        }
+    }
+
+
 }

+ 25 - 0
ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/Models/custom_clothes_orders.kt

@@ -0,0 +1,25 @@
+package com.example.uniqwearappproj.Models
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+@SerialName("custom_clothes_orders")
+data class custom_clothes_orders (
+    @SerialName("id")
+    val id: Int = 0,
+    @SerialName("price")
+    val price: Float,
+    @SerialName("created_at")
+    val created_at: String,
+    @SerialName("clothing_type_id")
+    val clothing_type_id: Int,
+    @SerialName("print_photo_url")
+    val print_photo_url: String,
+    @SerialName("user_id")
+    val user_id: Int?,
+    @SerialName("size")
+    val size: String,
+    @SerialName("count")
+    val count: String
+)

+ 23 - 0
ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/Models/custom_prints.kt

@@ -0,0 +1,23 @@
+package com.example.uniqwearappproj.Models
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+@SerialName("custom_prints")
+data class custom_prints (
+    @SerialName("id")
+    val id: Int,
+    @SerialName("user_id")
+    val clothing_type_id: Int,
+    @SerialName("name")
+    val name: String,
+    @SerialName("description")
+    val description: String,
+    @SerialName("image_url")
+    val image_url: String?,
+    @SerialName("price")
+    val price: Float,
+    @SerialName("created_at")
+    val created_at: String
+)

+ 2 - 10
ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/Models/order_items.kt

@@ -9,17 +9,9 @@ data class order_items (
     @SerialName("id")
     val id: Int? = 0,
     @SerialName("order_id")
-    val order_id: Int,
+    val id_custom: Int? = null, //может быть пустым
     @SerialName("ready_made_clothes_id")
-    val ready_made_clothes_id: Int? = null, //может быть пустым
-    @SerialName("custom_clothes_id")
-    val custom_clothes_id: Int? = null, //может быть пустым
-    @SerialName("size")
-    val size: String,
-    @SerialName("quantity")
-    val quantity: String,
-    @SerialName("price")
-    val price: Float,
+    val id_ready_made: Int? = null, //может быть пустым
     @SerialName("created_at")
     val created_at: String
 )

+ 3 - 5
ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/Models/orders.kt → ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/Models/ready_made_clothes_orders.kt

@@ -4,8 +4,8 @@ import kotlinx.serialization.SerialName
 import kotlinx.serialization.Serializable
 
 @Serializable
-@SerialName("orders")
-data class orders(
+@SerialName("ready_made_clothes_orders")
+data class ready_made_clothes_orders(
     @SerialName("id")
     val id: Int? = 0,
     @SerialName("user_id")
@@ -21,7 +21,5 @@ data class orders(
     @SerialName("count")
     val count: String,
     @SerialName("ready_made_id")
-    val ready_made_id: Int? = null, //может быть пустым
-    @SerialName("custom_made_id")
-    val custom_made_id: Int? = null, //может быть пустым
+    val ready_made_id: Int? = null //может быть пустым
 )

+ 40 - 19
ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/Screens/CartScreen.kt

@@ -1,6 +1,7 @@
 package com.example.uniqwearappproj.Screens
 
 import android.util.Log
+import android.widget.Toast
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.background
 import androidx.compose.foundation.border
@@ -31,6 +32,7 @@ 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
@@ -65,21 +67,24 @@ fun CartScreen(
     navController: NavHostController,
     cartProductList: List<ready_made_clothes>,
     viewModel: MainViewModel,
-    productId: Int?
+    productId: Int? = null
 ) {
     val currentProductId = remember { productId }
 
     val user by viewModel.user
 
+    val context = LocalContext.current
+
     val flag = remember { mutableStateOf(true) }
 
     // Найти товар с переданным id в списке
     val selectedProduct = cartProductList.find { it.id == currentProductId }
 
     // Проверить, найден ли товар
-    if (selectedProduct == null) {
+    if (selectedProduct == null && cartProductList.isEmpty()) {
+        // If no product found and cart is empty, show message
         Text(
-            text = "Товар не найден",
+            text = "Корзина пуста",
             fontSize = 18.sp,
             color = Color.White,
             textAlign = TextAlign.Center,
@@ -94,7 +99,7 @@ fun CartScreen(
     var expanded by remember { mutableStateOf(false) }
 
     // Вычислить общую цену для текущего товара
-    val totalPrice = selectedProduct.price.toDouble() * quantity
+    val totalPrice = selectedProduct!!.price.toDouble() * quantity
 
     if (flag.value) {
         viewModel.selectProfile()
@@ -151,7 +156,7 @@ fun CartScreen(
                     modifier = Modifier.fillMaxWidth(),
                     horizontalArrangement = Arrangement.SpaceBetween
                 ) {
-                    IconButton(onClick = { navController.navigate("auth_screen") }) {
+                    IconButton(onClick = { navController.navigate("main_screen") }) {
                         Image(
                             painter = painterResource(id = R.drawable.backbutton),
                             contentDescription = "Back Button",
@@ -164,8 +169,8 @@ fun CartScreen(
                         modifier = Modifier.size(50.dp)
                     )
                     // Аватарка
-                    if (photoUrl is AsyncImagePainter.State.Success){
-                        IconButton(onClick = { navController.navigate("user_profile_screen") }){
+                    if (photoUrl is AsyncImagePainter.State.Success) {
+                        IconButton(onClick = { navController.navigate("user_profile_screen") }) {
                             Box(
                                 modifier = Modifier
                                     .size(50.dp)
@@ -181,8 +186,8 @@ fun CartScreen(
                             }
                         }
                     }
-                    if (photoUrl is AsyncImagePainter.State.Loading){
-                        IconButton(onClick = { navController.navigate("user_profile_screen") }){
+                    if (photoUrl is AsyncImagePainter.State.Loading) {
+                        IconButton(onClick = { navController.navigate("user_profile_screen") }) {
                             Box(
                                 modifier = Modifier
                                     .size(50.dp)
@@ -194,7 +199,7 @@ fun CartScreen(
                             }
                         }
                     }
-                    if (photoUrl is AsyncImagePainter.State.Error){
+                    if (photoUrl is AsyncImagePainter.State.Error) {
                         IconButton(onClick = { navController.navigate("user_profile_screen") }) {
                             Box(
                                 modifier = Modifier
@@ -212,8 +217,6 @@ fun CartScreen(
                         }
                     }
                 }
-
-                // Данные выбранного товара
                 Column(
                     modifier = Modifier
                         .fillMaxWidth()
@@ -243,7 +246,10 @@ fun CartScreen(
                     //Изменение количества
                     Box(
                         modifier = Modifier
-                            .background(Color(0xFFD9D9D9).copy(alpha = 0.5f), RoundedCornerShape(10.dp)) // Заливка и закругленные углы
+                            .background(
+                                Color(0xFFD9D9D9).copy(alpha = 0.5f),
+                                RoundedCornerShape(10.dp)
+                            ) // Заливка и закругленные углы
                             .border(2.dp, Color(0xFF5F5EB7), RoundedCornerShape(10.dp)) // Рамка
                             .padding(4.dp) // Паддинг внутри бокса
                     ) {
@@ -296,13 +302,21 @@ fun CartScreen(
                         onExpandedChange = { expanded = !expanded },
                         modifier = Modifier
                             .background(Color(0xFFD9D9D9), RoundedCornerShape(10.dp))
-                            .width(142ы.dp)
+                            .width(142.dp)
                     ) {
                         TextField(
                             value = selectedSize,
                             onValueChange = {},
                             readOnly = true,
                             label = { Text("Размер") },
+                            colors = TextFieldDefaults.colors(
+                                unfocusedTextColor = Color.Black,
+                                unfocusedContainerColor = Color(0xFFD9D9D9).copy(alpha = 0.5f),
+                                focusedTextColor = Color.Black,
+                                focusedContainerColor = Color(0xFFD9D9D9).copy(alpha = 0.5f),
+                                focusedIndicatorColor = Color.Transparent,
+                                unfocusedIndicatorColor = Color.Transparent,
+                            ),
                             trailingIcon = {
                                 ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
                             },
@@ -364,6 +378,7 @@ fun CartScreen(
                     ) {
                         Text(
                             text = "Оплатить: ${"%.2f".format(totalPrice)} ₽",
+                            fontWeight = FontWeight.Bold,
                             color = Color.White
                         )
                     }
@@ -427,13 +442,18 @@ fun CartScreen(
                     }
                 }
 
+                // Иконка для перехода в корзину
                 IconButton(
-                    onClick = { navController.navigate("cart_screen") },
+                    onClick = {
+                        // Вместо перехода показываем сообщение
+                        Toast.makeText(context, "Вы уже на экране корзины!", Toast.LENGTH_SHORT).show()
+
+                    },
                     modifier = Modifier
-                        .size(64.dp) // Увеличение размера кнопки
+                        .size(64.dp)
                         .background(
                             color = Color(0xFFD9D9D9).copy(alpha = 0.5f),
-                            shape = RoundedCornerShape(10.dp) // Закругление углов
+                            shape = RoundedCornerShape(10.dp)
                         )
                 ) {
                     Box(
@@ -444,12 +464,13 @@ fun CartScreen(
                         Icon(
                             painter = painterResource(id = R.drawable.cart),
                             contentDescription = "Go to Cart",
-                            tint = Color(0xFFFFFFFF), // Цвет иконки
-                            modifier = Modifier.size(39.dp) // Увеличение размера иконки (при желании)
+                            tint = Color(0xFFFFFFFF),
+                            modifier = Modifier.size(39.dp)
                         )
                     }
                 }
 
+
                 IconButton(
                     onClick = { navController.navigate("user_profile_screen") },
                     modifier = Modifier

+ 13 - 7
ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/Screens/MainScreen.kt

@@ -1,5 +1,6 @@
 package com.example.uniqwearappproj.Screens
 
+import android.widget.Toast
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.background
 import androidx.compose.foundation.border
@@ -65,13 +66,12 @@ fun MainScreen(navController: NavHostController, viewModel: MainViewModel, cartP
     // Declare products as a mutable state list
     var products by remember { mutableStateOf<List<ready_made_clothes>>(listOf()) }
 
-    //var cartProducts by remember { mutableStateOf<List<ready_made_clothes>>(listOf()) }
+    val context = LocalContext.current
 
     val user by viewModel.user
 
     val flag = remember { mutableStateOf(true) }
 
-
     // Launch effect to fetch data when the screen is first launched
     LaunchedEffect(Unit) {
         withContext(Dispatchers.IO) {
@@ -361,13 +361,18 @@ fun MainScreen(navController: NavHostController, viewModel: MainViewModel, cartP
                     }
                 }
 
+                // Иконка для перехода в корзину
                 IconButton(
-                    onClick = { navController.navigate("cart_screen") },
+                    onClick = {
+                        // Вместо перехода показываем сообщение
+                        Toast.makeText(context, "Корзина пуста, для начала выберите товар!", Toast.LENGTH_SHORT).show()
+
+                    },
                     modifier = Modifier
-                        .size(64.dp) // Увеличение размера кнопки
+                        .size(64.dp)
                         .background(
                             color = Color(0xFFD9D9D9).copy(alpha = 0.5f),
-                            shape = RoundedCornerShape(10.dp) // Закругление углов
+                            shape = RoundedCornerShape(10.dp)
                         )
                 ) {
                     Box(
@@ -378,12 +383,13 @@ fun MainScreen(navController: NavHostController, viewModel: MainViewModel, cartP
                         Icon(
                             painter = painterResource(id = R.drawable.cart),
                             contentDescription = "Go to Cart",
-                            tint = Color(0xFFFFFFFF), // Цвет иконки
-                            modifier = Modifier.size(39.dp) // Увеличение размера иконки (при желании)
+                            tint = Color(0xFFFFFFFF),
+                            modifier = Modifier.size(39.dp)
                         )
                     }
                 }
 
+
                 IconButton(
                     onClick = { navController.navigate("user_profile_screen") },
                     modifier = Modifier

+ 15 - 6
ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/Screens/ThxForPaymentScreen.kt

@@ -1,5 +1,6 @@
 package com.example.uniqwearappproj.Screens
 
+import android.widget.Toast
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Arrangement
@@ -51,6 +52,8 @@ fun ThxForPaymentScreen(navController: NavHostController, viewModel: MainViewMod
     val user by viewModel.user
     val flag = remember { mutableStateOf(true) }
 
+    val context = LocalContext.current
+
     if (flag.value) {
         viewModel.selectProfile()
         flag.value = false
@@ -286,13 +289,18 @@ fun ThxForPaymentScreen(navController: NavHostController, viewModel: MainViewMod
                     }
                 }
 
+                // Иконка для перехода в корзину
                 IconButton(
-                    onClick = { navController.navigate("cart_screen") },
+                    onClick = {
+                        // Вместо перехода показываем сообщение
+                        Toast.makeText(context, "Корзина пуста, для начала выберите товар!", Toast.LENGTH_SHORT).show()
+
+                    },
                     modifier = Modifier
-                        .size(64.dp) // Увеличение размера кнопки
+                        .size(64.dp)
                         .background(
                             color = Color(0xFFD9D9D9).copy(alpha = 0.5f),
-                            shape = RoundedCornerShape(10.dp) // Закругление углов
+                            shape = RoundedCornerShape(10.dp)
                         )
                 ) {
                     Box(
@@ -303,12 +311,13 @@ fun ThxForPaymentScreen(navController: NavHostController, viewModel: MainViewMod
                         Icon(
                             painter = painterResource(id = R.drawable.cart),
                             contentDescription = "Go to Cart",
-                            tint = Color(0xFFFFFFFF), // Цвет иконки
-                            modifier = Modifier.size(39.dp) // Увеличение размера иконки (при желании)
+                            tint = Color(0xFFFFFFFF),
+                            modifier = Modifier.size(39.dp)
                         )
                     }
                 }
 
+
                 IconButton(
                     onClick = { navController.navigate("user_profile_screen") },
                     modifier = Modifier
@@ -325,7 +334,7 @@ fun ThxForPaymentScreen(navController: NavHostController, viewModel: MainViewMod
                     ) {
                         Icon(
                             painter = painterResource(id = R.drawable.account_circle),
-                            contentDescription = "Go to Profile",
+                            contentDescription = "Go to profile",
                             tint = Color(0xFFFFFFFF), // Цвет иконки
                             modifier = Modifier.size(39.dp) // Увеличение размера иконки (при желании)
                         )

+ 315 - 107
ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/Screens/printWorkshopScreen.kt

@@ -2,6 +2,7 @@ package com.example.uniqwearappproj.Screens
 
 import android.graphics.Bitmap
 import android.util.Base64
+import android.widget.Toast
 import androidx.compose.foundation.Canvas
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.background
@@ -28,20 +29,31 @@ import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material3.Button
 import androidx.compose.material3.ButtonDefaults
 import androidx.compose.material3.CircularProgressIndicator
+import androidx.compose.material3.DropdownMenuItem
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.ExposedDropdownMenuBox
+import androidx.compose.material3.ExposedDropdownMenuDefaults
 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.LaunchedEffect
+import androidx.compose.runtime.collectAsState
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clip
 import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.Size
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.drawscope.Stroke
 import androidx.compose.ui.graphics.toArgb
 import androidx.compose.ui.input.pointer.pointerInput
 import androidx.compose.ui.layout.ContentScale
@@ -58,10 +70,10 @@ import coil.request.ImageRequest
 import com.example.uniqwearappproj.MainViewModel
 import com.example.uniqwearappproj.R
 import java.io.ByteArrayOutputStream
-import java.net.URLEncoder
 
+@OptIn(ExperimentalMaterial3Api::class)
 @Composable
-fun PrintWorkshopScreen(navController: NavHostController, imageUrl: String?, viewModel: MainViewModel) {
+fun PrintWorkshopScreen(navController: NavHostController, idClothesType: Int?, imageUrl: String?, viewModel: MainViewModel) {
     var pathPoints by remember { mutableStateOf(mutableListOf<Offset>()) }
     var brushColor by remember { mutableStateOf(Color.Black) }
     val context = LocalContext.current
@@ -69,6 +81,30 @@ fun PrintWorkshopScreen(navController: NavHostController, imageUrl: String?, vie
     val stream = ByteArrayOutputStream()
     val imageData = stream.toByteArray()
 
+    // Состояния для хранения данных о товаре
+    val clothingType by viewModel.clothingType.collectAsState()
+    val isLoading by viewModel.isLoading.collectAsState()
+
+    //val selectedProduct = cartProductList.find { it.id == currentProductId }
+
+    // Запрос данных о товаре, если id передан
+    LaunchedEffect(idClothesType) {
+        if (idClothesType != null) {
+            viewModel.fetchClothesTypeById(idClothesType)
+        }
+    }
+
+    var quantity by rememberSaveable { mutableStateOf(1) }
+    val sizes = listOf("S", "M", "L", "X")
+    var selectedSize by remember { mutableStateOf(sizes[0]) }
+    var expanded by remember { mutableStateOf(false) }
+
+    // Установить фиксированную цену за услугу нанесения принта
+    val fixedPrice = 3220.0
+
+    // Вычислить общую цену, основываясь на количестве
+    val totalPrice = fixedPrice * quantity
+
     val user by viewModel.user
     val flag = remember { mutableStateOf(true) }
 
@@ -114,16 +150,21 @@ fun PrintWorkshopScreen(navController: NavHostController, imageUrl: String?, vie
             )
 
             // Хедер страницы
-            Box(modifier = Modifier.fillMaxWidth().padding(
-                top = WindowInsets.statusBars.asPaddingValues()
-                    .calculateTopPadding(), // Добавляем отступ от верхней части
-                bottom = 80.dp
-            ),) {
+            Box(
+                modifier = Modifier
+                    .fillMaxWidth()
+                    .padding(
+                        top = WindowInsets.statusBars
+                            .asPaddingValues()
+                            .calculateTopPadding(), // Добавляем отступ от верхней части
+                        bottom = 80.dp
+                    ),
+            ) {
                 Row(
                     modifier = Modifier.fillMaxWidth(),
                     horizontalArrangement = Arrangement.SpaceBetween
                 ) {
-                    IconButton(onClick = { navController.navigate("main_screen") }) {
+                    IconButton(onClick = { navController.navigate("template_selection_screen") }) {
                         Image(
                             painter = painterResource(id = R.drawable.backbutton),
                             contentDescription = "Back Button",
@@ -136,8 +177,8 @@ fun PrintWorkshopScreen(navController: NavHostController, imageUrl: String?, vie
                         modifier = Modifier.size(50.dp)
                     )
                     // Аватарка
-                    if (photoUrl is AsyncImagePainter.State.Success){
-                        IconButton(onClick = { navController.navigate("user_profile_screen") }){
+                    if (photoUrl is AsyncImagePainter.State.Success) {
+                        IconButton(onClick = { navController.navigate("user_profile_screen") }) {
                             Box(
                                 modifier = Modifier
                                     .size(50.dp)
@@ -153,8 +194,8 @@ fun PrintWorkshopScreen(navController: NavHostController, imageUrl: String?, vie
                             }
                         }
                     }
-                    if (photoUrl is AsyncImagePainter.State.Loading){
-                        IconButton(onClick = { navController.navigate("user_profile_screen") }){
+                    if (photoUrl is AsyncImagePainter.State.Loading) {
+                        IconButton(onClick = { navController.navigate("user_profile_screen") }) {
                             Box(
                                 modifier = Modifier
                                     .size(50.dp)
@@ -166,7 +207,7 @@ fun PrintWorkshopScreen(navController: NavHostController, imageUrl: String?, vie
                             }
                         }
                     }
-                    if (photoUrl is AsyncImagePainter.State.Error){
+                    if (photoUrl is AsyncImagePainter.State.Error) {
                         IconButton(onClick = { navController.navigate("user_profile_screen") }) {
                             Box(
                                 modifier = Modifier
@@ -190,7 +231,9 @@ fun PrintWorkshopScreen(navController: NavHostController, imageUrl: String?, vie
                 modifier = Modifier
                     .fillMaxSize()
                     .padding(
-                        top = WindowInsets.statusBars.asPaddingValues().calculateTopPadding(),
+                        top = WindowInsets.statusBars
+                            .asPaddingValues()
+                            .calculateTopPadding(),
                         bottom = 80.dp,
                         start = 16.dp, // Добавляем отступы слева
                         end = 16.dp
@@ -198,106 +241,264 @@ fun PrintWorkshopScreen(navController: NavHostController, imageUrl: String?, vie
                 verticalArrangement = Arrangement.Center,
                 horizontalAlignment = Alignment.CenterHorizontally
             ) {
-                Text(
-                    text = "Мастерская",
-                    fontSize = 20.sp,
-                    fontWeight = FontWeight.Bold,
-                    color = Color.White,
-                    modifier = Modifier.padding(start = 16.dp) // Добавляем отступ слева
-                )
-                Text(
-                    text = "Нарисуйте свой принт:",
-                    fontSize = 18.sp,
-                    modifier = Modifier
-                        .padding(
-                            top = 8.dp,
-                            bottom = 16.dp,
-                            start = 16.dp
-                        ), // Добавляем отступ слева
-                    color = Color.White
-                )
-                Box(
-                    modifier = Modifier
-                        .fillMaxWidth()
-                        .aspectRatio(1f)
-                        .padding(16.dp)
-                ) {
-                    if (imageUrl != null) {
-                        AsyncImage(
-                            model = imageUrl,
-                            contentDescription = "Selected Clothing Image",
-                            modifier = Modifier
-                                .size(400.dp)
-                                .clip(RoundedCornerShape(13.dp))
-                                .border(4.dp, Color.Gray, RoundedCornerShape(13.dp))
-                                .align(Alignment.Center),
-                            contentScale = ContentScale.Crop
+                if (isLoading) {
+                    CircularProgressIndicator()
+                } else {
+                    if (clothingType != null) {
+                        Text(
+                            text = "Мастерская",
+                            fontSize = 20.sp,
+                            fontWeight = FontWeight.Bold,
+                            color = Color.White,
+                            modifier = Modifier.padding(start = 16.dp) // Добавляем отступ слева
                         )
-                    } else {
                         Text(
-                            text = "Ошибка загрузки изображения",
-                            color = Color.Red,
-                            modifier = Modifier.align(Alignment.Center)
+                            text = "Нарисуйте свой принт:",
+                            fontSize = 18.sp,
+                            modifier = Modifier
+                                .padding(
+                                    top = 8.dp,
+                                    bottom = 16.dp,
+                                    start = 16.dp
+                                ), // Добавляем отступ слева
+                            color = Color.White
                         )
-                    }
-                    Canvas(
-                        modifier = Modifier
-                            .fillMaxSize()
-                            .pointerInput(Unit) {
-                                detectDragGestures { change, _ ->
-                                    val newPoint = change.position
-                                    pathPoints = (pathPoints + newPoint).toMutableList()
+                        Box(
+                            modifier = Modifier
+                                .fillMaxWidth()
+                                .aspectRatio(1f)
+                                .padding(16.dp)
+                        ) {
+                            if (imageUrl != null) {
+                                AsyncImage(
+                                    model = clothingType!!.image_url,
+                                    contentDescription = "Selected Clothing Image",
+                                    modifier = Modifier
+                                        .size(400.dp)
+                                        .clip(RoundedCornerShape(13.dp))
+                                        .border(4.dp, Color.Gray, RoundedCornerShape(13.dp))
+                                        .align(Alignment.Center),
+                                    contentScale = ContentScale.Crop
+                                )
+                            } else {
+                                Text(
+                                    text = "Ошибка загрузки изображения",
+                                    color = Color.Red,
+                                    modifier = Modifier.align(Alignment.Center)
+                                )
+                            }
+                            Canvas(
+                                modifier = Modifier
+                                    .fillMaxSize()
+                                    .pointerInput(Unit) {
+                                        detectDragGestures { change, _ ->
+                                            val canvasWidth = size.width
+                                            val canvasHeight = size.height
+
+                                            // Вычисляем границы области рисования (центр 240x240)
+                                            val centerX = canvasWidth / 2
+                                            val centerY = canvasHeight / 2
+                                            val drawingAreaSize = 335.dp.toPx() // Размер области 240x240
+                                            val leftBound = centerX - drawingAreaSize / 2
+                                            val rightBound = centerX + drawingAreaSize / 2
+                                            val topBound = centerY - drawingAreaSize / 2
+                                            val bottomBound = centerY + drawingAreaSize / 2
+
+                                            val newPoint = change.position
+
+                                            // Проверяем, входит ли точка в разрешённую область
+                                            if (newPoint.x in leftBound..rightBound && newPoint.y in topBound..bottomBound) {
+                                                pathPoints = (pathPoints + newPoint).toMutableList()
+                                            }
+                                        }
+                                    }
+                            ) {
+                                val canvasWidth = size.width
+                                val canvasHeight = size.height
+
+                                // Вычисляем границы разрешенной области (центр 240x240)
+                                val centerX = canvasWidth / 2
+                                val centerY = canvasHeight / 2
+                                val drawingAreaSize = 335.dp.toPx() // Размер области 240x240
+                                val leftBound = centerX - drawingAreaSize / 2
+                                val rightBound = centerX + drawingAreaSize / 2
+                                val topBound = centerY - drawingAreaSize / 2
+                                val bottomBound = centerY + drawingAreaSize / 2
+
+                                // Удаляем или делаем рамку прозрачной (в данном случае не рисуем её)
+                                 drawRect(
+                                     color = Color.Transparent,
+                                     topLeft = Offset(leftBound, topBound),
+                                     size = Size(drawingAreaSize, drawingAreaSize),
+                                     style = Stroke(width = 4f)
+                                 )
+
+                                // Рисуем линии только внутри разрешенной области
+                                for (i in 1 until pathPoints.size) {
+                                    if (pathPoints[i - 1].x in leftBound..rightBound &&
+                                        pathPoints[i - 1].y in topBound..bottomBound &&
+                                        pathPoints[i].x in leftBound..rightBound &&
+                                        pathPoints[i].y in topBound..bottomBound
+                                    ) {
+                                        drawLine(
+                                            color = brushColor,
+                                            start = pathPoints[i - 1],
+                                            end = pathPoints[i],
+                                            strokeWidth = 5f
+                                        )
+                                    }
                                 }
                             }
-                    ) {
-                        for (i in 1 until pathPoints.size) {
-                            drawLine(
-                                color = brushColor,
-                                start = pathPoints[i - 1],
-                                end = pathPoints[i],
-                                strokeWidth = 5f
+                        }
+                        Spacer(modifier = Modifier.height(8.dp))
+                        ClearColor(onClear = { pathPoints = mutableListOf() })
+
+                        Spacer(modifier = Modifier.height(8.dp))
+
+                        //Изменение количества
+                        Box(
+                            modifier = Modifier
+                                .background(Color(0xFFD9D9D9).copy(alpha = 0.5f), RoundedCornerShape(10.dp)) // Заливка и закругленные углы
+                                .border(2.dp, Color(0xFF5F5EB7), RoundedCornerShape(10.dp)) // Рамка
+                                .padding(4.dp) // Паддинг внутри бокса
+                        ) {
+                            // Управление количеством
+                            Row(
+                                verticalAlignment = Alignment.CenterVertically,
+                                horizontalArrangement = Arrangement.Center // Центрирование содержимого
+                            ) {
+                                IconButton(
+                                    onClick = { quantity++ },
+                                    modifier = Modifier.size(55.dp)
+                                ) {
+                                    Icon(
+                                        painter = painterResource(id = R.drawable.add),
+                                        contentDescription = "Increase Quantity",
+                                        tint = Color.White,
+                                        modifier = Modifier.size(28.dp) // Увеличение размера иконки
+
+                                    )
+                                }
+
+
+                                Text(
+                                    text = "$quantity",
+                                    fontSize = 20.sp,
+                                    color = Color.White,
+                                    modifier = Modifier.padding(horizontal = 8.dp)
+                                )
+
+                                IconButton(
+                                    onClick = { if (quantity > 1) quantity-- },
+                                    modifier = Modifier.size(55.dp)
+                                ) {
+                                    Icon(
+                                        painter = painterResource(id = R.drawable.minus),
+                                        contentDescription = "Decrease Quantity",
+                                        tint = Color.White,
+                                        modifier = Modifier.size(28.dp) // Увеличение размера иконки
+                                    )
+                                }
+                            }
+                        }
+
+
+                        Spacer(modifier = Modifier.height(8.dp))
+
+                        // Выбор размера
+                        ExposedDropdownMenuBox(
+                            expanded = expanded,
+                            onExpandedChange = { expanded = !expanded },
+                            modifier = Modifier
+                                .background(Color(0xFFD9D9D9), RoundedCornerShape(10.dp))
+                                .width(142.dp)
+                        ) {
+                            TextField(
+                                value = selectedSize,
+                                onValueChange = {},
+                                readOnly = true,
+                                label = { Text("Размер") },
+                                colors = TextFieldDefaults.colors(
+                                    unfocusedTextColor = Color.Black,
+                                    unfocusedContainerColor = Color(0xFFD9D9D9).copy(alpha = 0.5f),
+                                    focusedTextColor = Color.Black,
+                                    focusedContainerColor = Color(0xFFD9D9D9).copy(alpha = 0.5f),
+                                    focusedIndicatorColor = Color.Transparent,
+                                    unfocusedIndicatorColor = Color.Transparent,
+                                ),
+                                trailingIcon = {
+                                    ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
+                                },
+                                modifier = Modifier
+                                    .menuAnchor()
+                                    .background(Color(0xFFD9D9D9), RoundedCornerShape(10.dp))
+                                    .border(2.dp, Color(0xFF5F5EB7), RoundedCornerShape(10.dp))
                             )
+                            ExposedDropdownMenu(
+                                expanded = expanded,
+                                onDismissRequest = { expanded = false }
+                            ) {
+                                sizes.forEach { size ->
+                                    DropdownMenuItem(
+                                        text = { Text(size) },
+                                        onClick = {
+                                            selectedSize = size
+                                            expanded = false
+                                        }
+                                    )
+                                }
+                            }
                         }
-                    }
-                }
-                Spacer(modifier = Modifier.height(8.dp))
-                ClearColor(onClear = { pathPoints = mutableListOf() })
-                Spacer(modifier = Modifier.height(8.dp))
-                Button(
-                    onClick = {
-                        // Save the drawing to a bitmap
-                        val bitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888)
-                        val canvas = android.graphics.Canvas(bitmap)
-                        canvas.drawColor(android.graphics.Color.WHITE) // Background color
-                        for (i in 1 until pathPoints.size) {
-                            canvas.drawLine(
-                                pathPoints[i - 1].x,
-                                pathPoints[i - 1].y,
-                                pathPoints[i].x,
-                                pathPoints[i].y,
-                                android.graphics.Paint().apply {
+
+                        Spacer(modifier = Modifier.height(8.dp))
+                        Button(
+                            onClick = {
+                                // Размер холста, чтобы он был достаточен для изображения
+                                val width = 800 // Примерная ширина холста
+                                val height = 800 // Примерная высота холста
+
+                                // Создаем Bitmap с нужными размерами
+                                val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
+                                val canvas = android.graphics.Canvas(bitmap)
+                                canvas.drawColor(android.graphics.Color.WHITE) // Фон рисунка
+
+                                // Рисуем линии из pathPoints на canvas
+                                val paint = android.graphics.Paint().apply {
                                     color = brushColor.toArgb()
                                     strokeWidth = 5f
+                                    isAntiAlias = true
                                 }
+                                for (i in 1 until pathPoints.size) {
+                                    canvas.drawLine(
+                                        pathPoints[i - 1].x,
+                                        pathPoints[i - 1].y,
+                                        pathPoints[i].x,
+                                        pathPoints[i].y,
+                                        paint
+                                    )
+                                }
+
+                                // Сохранение рисунка и других данных через функцию ViewModel
+                                viewModel.saveCanvasDrawingAsAvatar(bitmap,
+                                    totalPrice.toFloat(), selectedSize,
+                                    quantity.toString()
+                                )
+                                navController.navigate("thx_for_payment_screen")
+                            },
+                            modifier = Modifier
+                                .width(240.dp)
+                                .height(48.dp),
+                            colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF5F5EB7)),
+                            shape = RoundedCornerShape(12.dp)
+                        ) {
+                            Text(
+                                text = "Оплатить: ${"%.2f".format(totalPrice)} ₽",
+                                fontWeight = FontWeight.Bold,
+                                fontSize = 20.sp,
+                                color = Color.White
                             )
                         }
-
-                        // Save to drawingBitmap and navigate to CartScreen
-                        drawingBitmap.value = bitmap
-                        val encodedImage = encodeBitmapToBase64(drawingBitmap.value!!)
-                        val encodedImageUrlSafe = URLEncoder.encode(encodedImage, "UTF-8")
-                        navController.navigate("cart_screen/$encodedImageUrlSafe")
-                    },
-                    modifier = Modifier.width(200.dp).height(48.dp),
-                    colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF5F5EB7)),
-                    shape = RoundedCornerShape(12.dp)
-                ) {
-                    Text(
-                        text = "Готово",
-                        fontWeight = FontWeight.Bold,
-                        fontSize = 20.sp,
-                        color = Color.White
-                    )
+                    }
                 }
             }
 
@@ -359,13 +560,18 @@ fun PrintWorkshopScreen(navController: NavHostController, imageUrl: String?, vie
                     }
                 }
 
+                // Иконка для перехода в корзину
                 IconButton(
-                    onClick = { navController.navigate("cart_screen") },
+                    onClick = {
+                        // Вместо перехода показываем сообщение
+                        Toast.makeText(context, "Корзина пуста, для начала выберите товар!", Toast.LENGTH_SHORT).show()
+
+                    },
                     modifier = Modifier
-                        .size(64.dp) // Увеличение размера кнопки
+                        .size(64.dp)
                         .background(
                             color = Color(0xFFD9D9D9).copy(alpha = 0.5f),
-                            shape = RoundedCornerShape(10.dp) // Закругление углов
+                            shape = RoundedCornerShape(10.dp)
                         )
                 ) {
                     Box(
@@ -376,12 +582,13 @@ fun PrintWorkshopScreen(navController: NavHostController, imageUrl: String?, vie
                         Icon(
                             painter = painterResource(id = R.drawable.cart),
                             contentDescription = "Go to Cart",
-                            tint = Color(0xFFFFFFFF), // Цвет иконки
-                            modifier = Modifier.size(39.dp) // Увеличение размера иконки (при желании)
+                            tint = Color(0xFFFFFFFF),
+                            modifier = Modifier.size(39.dp)
                         )
                     }
                 }
 
+
                 IconButton(
                     onClick = { navController.navigate("user_profile_screen") },
                     modifier = Modifier
@@ -409,6 +616,7 @@ fun PrintWorkshopScreen(navController: NavHostController, imageUrl: String?, vie
     }
 }
 
+
 @Composable
 fun ClearColor(onClear: () -> Unit) {
     Row(

+ 17 - 14
ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/Screens/templateSelectionScreen.kt

@@ -1,5 +1,6 @@
 package com.example.uniqwearappproj.Screens
 
+import android.widget.Toast
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.background
 import androidx.compose.foundation.border
@@ -44,11 +45,9 @@ import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.painterResource
 import androidx.compose.ui.text.font.FontWeight
 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.sp
 import androidx.navigation.NavHostController
-import androidx.navigation.compose.rememberNavController
 import coil.compose.AsyncImage
 import coil.compose.AsyncImagePainter
 import coil.compose.rememberAsyncImagePainter
@@ -66,6 +65,8 @@ import java.net.URLEncoder
 fun TemplateSelectionScreen(navController: NavHostController, viewModel: MainViewModel) {
     var clothingTypes by remember { mutableStateOf<List<clothing_types>>(listOf()) }
 
+    val context = LocalContext.current
+
     val user by viewModel.user
 
     val flag = remember { mutableStateOf(true) }
@@ -277,13 +278,9 @@ fun TemplateSelectionScreen(navController: NavHostController, viewModel: MainVie
                                 // Button aligned to the right
                                 IconButton(
                                     onClick = {
+                                        val encodedImageUrl = URLEncoder.encode(clothingType.image_url, "UTF-8")
                                         navController.navigate(
-                                            "print_workshop_screen/${
-                                                URLEncoder.encode(
-                                                    clothingType.image_url,
-                                                    "UTF-8"
-                                                )
-                                            }"
+                                            "print_workshop_screen/${clothingType.id}/$encodedImageUrl"
                                         )
                                     },
                                     modifier = Modifier.size(56.dp) // Увеличение размера кнопки
@@ -291,7 +288,7 @@ fun TemplateSelectionScreen(navController: NavHostController, viewModel: MainVie
                                     Icon(
                                         painter = painterResource(id = R.drawable.add_circle),
                                         contentDescription = "Add to Cart",
-                                        tint = Color(0xFF5F5EB7), //цвет иконки
+                                        tint = Color(0xFF5F5EB7), // цвет иконки
                                         modifier = Modifier.size(39.dp) // Увеличение размера иконки (при желании)
                                     )
                                 }
@@ -358,13 +355,18 @@ fun TemplateSelectionScreen(navController: NavHostController, viewModel: MainVie
                     }
                 }
 
+                // Иконка для перехода в корзину
                 IconButton(
-                    onClick = { navController.navigate("cart_screen") },
+                    onClick = {
+                        // Вместо перехода показываем сообщение
+                        Toast.makeText(context, "Корзина пуста, для начала выберите товар!", Toast.LENGTH_SHORT).show()
+
+                    },
                     modifier = Modifier
-                        .size(64.dp) // Увеличение размера кнопки
+                        .size(64.dp)
                         .background(
                             color = Color(0xFFD9D9D9).copy(alpha = 0.5f),
-                            shape = RoundedCornerShape(10.dp) // Закругление углов
+                            shape = RoundedCornerShape(10.dp)
                         )
                 ) {
                     Box(
@@ -375,12 +377,13 @@ fun TemplateSelectionScreen(navController: NavHostController, viewModel: MainVie
                         Icon(
                             painter = painterResource(id = R.drawable.cart),
                             contentDescription = "Go to Cart",
-                            tint = Color(0xFFFFFFFF), // Цвет иконки
-                            modifier = Modifier.size(39.dp) // Увеличение размера иконки (при желании)
+                            tint = Color(0xFFFFFFFF),
+                            modifier = Modifier.size(39.dp)
                         )
                     }
                 }
 
+
                 IconButton(
                     onClick = { navController.navigate("user_profile_screen") },
                     modifier = Modifier

+ 33 - 18
ProjectInAndroidStudio/app/src/main/java/com/example/uniqwearappproj/Screens/userProfileScreen.kt

@@ -1,6 +1,7 @@
 package com.example.uniqwearappproj.Screens
 
 import android.graphics.BitmapFactory
+import android.widget.Toast
 import androidx.activity.compose.rememberLauncherForActivityResult
 import androidx.activity.result.PickVisualMediaRequest
 import androidx.activity.result.contract.ActivityResultContracts
@@ -65,6 +66,7 @@ fun UserProfileScreen(navController: NavHostController, viewModel: MainViewModel
     val context = LocalContext.current
     //Переменная для кнопки обновления
 
+
     val user by viewModel.user
 
     if (flag.value) {
@@ -643,7 +645,7 @@ fun UserProfileScreen(navController: NavHostController, viewModel: MainViewModel
                         }
                     }
 
-                    // Навигационная панель
+                    // Панель навигации в приложении
                     Row(
                         modifier = Modifier
                             .fillMaxWidth()
@@ -658,47 +660,56 @@ fun UserProfileScreen(navController: NavHostController, viewModel: MainViewModel
                         IconButton(
                             onClick = { navController.navigate("main_screen") },
                             modifier = Modifier
-                                .size(64.dp)
+                                .size(64.dp) // Увеличение размера кнопки
                                 .background(
                                     color = Color(0xFFD9D9D9).copy(alpha = 0.5f),
-                                    shape = RoundedCornerShape(10.dp)
+                                    shape = RoundedCornerShape(10.dp) // Закругление углов
                                 )
                         ) {
                             Box(
                                 contentAlignment = Alignment.Center,
-                                modifier = Modifier.size(64.dp)
+                                modifier = Modifier
+                                    .size(64.dp)
                             ) {
                                 Icon(
                                     painter = painterResource(id = R.drawable.ivector),
                                     contentDescription = "Go to Main",
-                                    tint = Color(0xFFFFFFFF),
-                                    modifier = Modifier.size(39.dp)
+                                    tint = Color(0xFFFFFFFF), // Цвет иконки
+                                    modifier = Modifier.size(39.dp) // Увеличение размера иконки (при желании)
                                 )
                             }
                         }
+
                         IconButton(
                             onClick = { navController.navigate("template_selection_screen") },
                             modifier = Modifier
-                                .size(64.dp)
+                                .size(64.dp) // Увеличение размера кнопки
                                 .background(
                                     color = Color(0xFFD9D9D9).copy(alpha = 0.5f),
-                                    shape = RoundedCornerShape(10.dp)
+                                    shape = RoundedCornerShape(10.dp) // Закругление углов
                                 )
                         ) {
                             Box(
                                 contentAlignment = Alignment.Center,
-                                modifier = Modifier.size(64.dp)
+                                modifier = Modifier
+                                    .size(64.dp)
                             ) {
                                 Icon(
                                     painter = painterResource(id = R.drawable.add),
                                     contentDescription = "Go to create",
-                                    tint = Color(0xFFFFFFFF),
-                                    modifier = Modifier.size(39.dp)
+                                    tint = Color(0xFFFFFFFF), // Цвет иконки
+                                    modifier = Modifier.size(39.dp) // Увеличение размера иконки (при желании)
                                 )
                             }
                         }
+
+                        // Иконка для перехода в корзину
                         IconButton(
-                            onClick = { navController.navigate("cart_screen") },
+                            onClick = {
+                                // Вместо перехода показываем сообщение
+                                Toast.makeText(context, "Корзина пуста, для начала выберите товар!", Toast.LENGTH_SHORT).show()
+
+                            },
                             modifier = Modifier
                                 .size(64.dp)
                                 .background(
@@ -708,7 +719,8 @@ fun UserProfileScreen(navController: NavHostController, viewModel: MainViewModel
                         ) {
                             Box(
                                 contentAlignment = Alignment.Center,
-                                modifier = Modifier.size(64.dp)
+                                modifier = Modifier
+                                    .size(64.dp)
                             ) {
                                 Icon(
                                     painter = painterResource(id = R.drawable.cart),
@@ -718,24 +730,27 @@ fun UserProfileScreen(navController: NavHostController, viewModel: MainViewModel
                                 )
                             }
                         }
+
+
                         IconButton(
                             onClick = { navController.navigate("user_profile_screen") },
                             modifier = Modifier
-                                .size(64.dp)
+                                .size(64.dp) // Увеличение размера кнопки
                                 .background(
                                     color = Color(0xFFD9D9D9).copy(alpha = 0.5f),
-                                    shape = RoundedCornerShape(10.dp)
+                                    shape = RoundedCornerShape(10.dp) // Закругление углов
                                 )
                         ) {
                             Box(
                                 contentAlignment = Alignment.Center,
-                                modifier = Modifier.size(64.dp)
+                                modifier = Modifier
+                                    .size(64.dp)
                             ) {
                                 Icon(
                                     painter = painterResource(id = R.drawable.account_circle),
                                     contentDescription = "Go to profile",
-                                    tint = Color(0xFFFFFFFF),
-                                    modifier = Modifier.size(39.dp)
+                                    tint = Color(0xFFFFFFFF), // Цвет иконки
+                                    modifier = Modifier.size(39.dp) // Увеличение размера иконки (при желании)
                                 )
                             }
                         }

+ 2 - 0
ProjectInAndroidStudio/gradle/libs.versions.toml

@@ -16,6 +16,7 @@ composeBom = "2024.04.01"
 navigationRuntimeKtx = "2.8.3"
 navigationCompose = "2.8.3"
 firebaseFirestoreKtx = "25.1.1"
+firebaseCrashlyticsBuildtools = "3.0.2"
 
 [libraries]
 androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -44,6 +45,7 @@ ktor-client-android = { module = "io.ktor:ktor-client-android", version.ref = "k
 postgrest-kt = { module = "io.github.jan-tennert.supabase:postgrest-kt" }
 realtime-kt = { module = "io.github.jan-tennert.supabase:realtime-kt" }
 firebase-firestore-ktx = { group = "com.google.firebase", name = "firebase-firestore-ktx", version.ref = "firebaseFirestoreKtx" }
+firebase-crashlytics-buildtools = { group = "com.google.firebase", name = "firebase-crashlytics-buildtools", version.ref = "firebaseCrashlyticsBuildtools" }
 
 [plugins]
 android-application = { id = "com.android.application", version.ref = "agp" }

BIN=BIN
Скриншоты дизайна/Страницы создания принта на одежде.png