diff --git a/.gitignore b/.gitignore index a8b0d1d..aa724b7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,35 +1,15 @@ -# ---> Android -# Gradle files -.gradle/ -build/ - -# Local configuration file (sdk path, etc) -local.properties - -# Log/OS Files -*.log - -# Android Studio generated files and folders -captures/ -.externalNativeBuild/ -.cxx/ -*.apk -output.json - -# IntelliJ *.iml -.idea/ -misc.xml -deploymentTargetDropDown.xml -render.experimental.xml - -# Keystore files -*.jks -*.keystore - -# Google Services (e.g. APIs or Firebase) -google-services.json - -# Android Profiling -*.hprof - +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..b589d56 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..ae388c2 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..103e00c --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,32 @@ + + + + \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml new file mode 100644 index 0000000..0fc3113 --- /dev/null +++ b/.idea/kotlinc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..8978d23 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/.idea/.gitignore b/app/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/app/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/app/.idea/gradle.xml b/app/.idea/gradle.xml new file mode 100644 index 0000000..0364d75 --- /dev/null +++ b/app/.idea/gradle.xml @@ -0,0 +1,14 @@ + + + + + + + \ No newline at end of file diff --git a/app/.idea/misc.xml b/app/.idea/misc.xml new file mode 100644 index 0000000..a318cae --- /dev/null +++ b/app/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/app/.idea/vcs.xml b/app/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/app/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 89a08d2..f165261 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -4,17 +4,20 @@ plugins { } android { - namespace = "com.example.flowershop" - compileSdk = 33 + namespace = "com.example.flowershopapp" + compileSdk = 34 defaultConfig { - applicationId = "com.example.flowershop" - minSdk = 24 + applicationId = "com.example.flowershopapp" + minSdk = 25 targetSdk = 33 versionCode = 1 versionName = "1.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + vectorDrawables { + useSupportLibrary = true + } } buildTypes { @@ -34,21 +37,37 @@ android { jvmTarget = "1.8" } buildFeatures { - viewBinding = true + compose = true + } + composeOptions { + kotlinCompilerExtensionVersion = "1.4.3" + } + packaging { + resources { + excludes += "/META-INF/{AL2.0,LGPL2.1}" + } } } dependencies { - - implementation("androidx.core:core-ktx:1.9.0") - implementation("androidx.appcompat:appcompat:1.6.1") - implementation("com.google.android.material:material:1.8.0") - implementation("androidx.constraintlayout:constraintlayout:2.1.4") - implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2") - implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2") - implementation("androidx.navigation:navigation-fragment-ktx:2.7.3") - implementation("androidx.navigation:navigation-ui-ktx:2.7.3") + implementation("com.google.accompanist:accompanist-systemuicontroller:0.28.0") + implementation("com.google.accompanist:accompanist-pager:0.18.0") + implementation("androidx.navigation:navigation-compose:2.7.4") + implementation("androidx.core:core-ktx:1.12.0") + implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2") + implementation("androidx.activity:activity-compose:1.8.0") + implementation(platform("androidx.compose:compose-bom:2023.10.01")) + implementation("androidx.compose.ui:ui") + implementation("androidx.compose.ui:ui-graphics") + implementation("androidx.compose.ui:ui-tooling-preview") + implementation("androidx.compose.material3:material3") + implementation("androidx.navigation:navigation-runtime-ktx:2.7.4") + implementation("androidx.wear.compose:compose-material3:1.0.0-alpha14") testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.1.5") androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") + androidTestImplementation(platform("androidx.compose:compose-bom:2023.10.01")) + androidTestImplementation("androidx.compose.ui:ui-test-junit4") + debugImplementation("androidx.compose.ui:ui-tooling") + debugImplementation("androidx.compose.ui:ui-test-manifest") } \ No newline at end of file diff --git a/app/src/androidTest/java/com/example/flowershopapp/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/example/flowershopapp/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..c11fa6e --- /dev/null +++ b/app/src/androidTest/java/com/example/flowershopapp/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.example.flowershopapp + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.example.flowershopapp", appContext.packageName) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e821932..746760f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -10,12 +10,13 @@ android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/Theme.FlowerShop" + android:theme="@style/Theme.FlowerShopApp" tools:targetApi="31"> + android:label="@string/app_name" + android:theme="@style/Theme.FlowerShopApp"> diff --git a/app/src/main/java/com/example/flowershopapp/Bouquet/ComposeUI/BouquetCatalog.kt b/app/src/main/java/com/example/flowershopapp/Bouquet/ComposeUI/BouquetCatalog.kt new file mode 100644 index 0000000..782cc00 --- /dev/null +++ b/app/src/main/java/com/example/flowershopapp/Bouquet/ComposeUI/BouquetCatalog.kt @@ -0,0 +1,125 @@ +package com.example.flowershopapp.Bouquet.ComposeUI + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.wrapContentWidth +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.CardElevation +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.navigation.NavController +import com.example.flowershopapp.Bouquet.Model.Bouquet +import com.example.flowershopapp.ComposeUI.Navigation.Screen +import com.example.flowershopapp.Bouquet.Model.getBouquets +import com.example.flowershopapp.R + +@Composable +fun BouquetCatalog(navController: NavController) { + val bouquets = getBouquets() + + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text(text = "Каталог букетов", fontFamily = FontFamily.Serif, fontSize = 40.sp,fontWeight = FontWeight.W600) + LazyColumn( + modifier = Modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + items(bouquets) { bouquet -> + Row(modifier = Modifier.padding(top = 20.dp), horizontalArrangement = Arrangement.SpaceBetween) { + BouquetCard(bouquet = bouquet) + } + } + } + } +} + +@Composable +fun BouquetCard(bouquet: Bouquet) { + Card( + modifier = Modifier + .padding(16.dp), + elevation = CardDefaults.cardElevation( + defaultElevation = 10.dp + ), + colors = CardDefaults.cardColors( + containerColor = Color.White + ) + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Box(contentAlignment = Alignment.TopEnd) { + Image( + painter = painterResource(id = bouquet.imageResourceId), + contentDescription = null, + modifier = Modifier + .height(250.dp) + .width(250.dp) + .clip(shape = RoundedCornerShape(10.dp)), + contentScale = ContentScale.Crop + ) + Box(Modifier.clip(RoundedCornerShape(10.dp)).clickable { }) { + Icon( + painter = painterResource(id = R.drawable.icon_heart), + contentDescription = null, + modifier = Modifier + .size(40.dp) + .clip(shape = RoundedCornerShape(10.dp)) + ) + } + } + Spacer(modifier = Modifier.height(8.dp)) + Text(text = bouquet.name, fontFamily = FontFamily.Serif, fontSize = 25.sp) + //Spacer(modifier = Modifier.height(1.dp)) + Text(text = "${bouquet.quantityOfFlowers} цветов", fontFamily = FontFamily.Serif, fontSize = 19.sp) + //Spacer(modifier = Modifier.height(8.dp)) + Text(text = "${bouquet.price}", fontFamily = FontFamily.Serif, fontSize = 19.sp) + Row(horizontalArrangement = Arrangement.Center) { + Button(modifier = Modifier + .width(115.dp), shape = RoundedCornerShape(8.dp), onClick = { }, + colors = ButtonDefaults.buttonColors( + containerColor = colorResource(id = R.color.button) + )) { + Text("Купить") + } + Spacer(modifier = Modifier.width(8.dp)) + Button(modifier = Modifier + .width(115.dp), shape = RoundedCornerShape(8.dp), onClick = { }, + colors = ButtonDefaults.buttonColors( + containerColor = colorResource(id = R.color.button) + )) { + Text("В корзину") + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/flowershopapp/Bouquet/Model/Bouquet.kt b/app/src/main/java/com/example/flowershopapp/Bouquet/Model/Bouquet.kt new file mode 100644 index 0000000..2eae97d --- /dev/null +++ b/app/src/main/java/com/example/flowershopapp/Bouquet/Model/Bouquet.kt @@ -0,0 +1,31 @@ +package com.example.flowershopapp.Bouquet.Model + +import com.example.flowershopapp.R +import java.io.Serializable + +data class Bouquet( + val id: Int, + val name: String, + val quantityOfFlowers: Int, + val price: Int, + val imageResourceId: Int, + val quantityInCart: Int = 0 +) : Serializable + +fun getBouquets(): List { + return listOf( + Bouquet(1, "Нежная Роза", 12, 2500, R.drawable.image_bouquet1), + Bouquet(2, "Лилия Элегия", 15, 2900, R.drawable.image_bouquet2), + Bouquet(5, "Обаятельный Гвоздик", 18, 1999, R.drawable.image_bouquet4), + Bouquet(6, "Мечта о Маргаритке", 25, 3999, R.drawable.image_bouquet5), + Bouquet(7, "Сияние Подсолнуха", 8, 2799, R.drawable.image_bouquet6), + Bouquet(8, "Разнообразие Сада", 30, 4999, R.drawable.image_bouquet7), + Bouquet(9, "Лесной Букет", 22, 3399, R.drawable.image_bouquet8) + ) +} +fun getBouquetsFromCart(): List { + return listOf( + Bouquet(1, "Нежная Роза", 12, 2500, R.drawable.image_bouquet1, 1), + Bouquet(2, "Лилия Элегия", 15, 2900, R.drawable.image_bouquet2, 2), + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/example/flowershopapp/ComposeUI/Boot.kt b/app/src/main/java/com/example/flowershopapp/ComposeUI/Boot.kt new file mode 100644 index 0000000..0468cf1 --- /dev/null +++ b/app/src/main/java/com/example/flowershopapp/ComposeUI/Boot.kt @@ -0,0 +1,33 @@ +package com.example.flowershopapp.ComposeUI + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +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.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.navigation.NavController +import com.example.flowershopapp.R +import kotlinx.coroutines.delay + +@Composable +fun Boot(navController: NavController){ + LaunchedEffect(Unit) { + delay(2000) + navController.navigate("Login") + } + Box(modifier = Modifier.fillMaxSize()) { + Image( + painter = painterResource(id = R.drawable.image_boot), + contentDescription = "", + contentScale = ContentScale.FillBounds, + modifier = Modifier.fillMaxSize() + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/flowershopapp/ComposeUI/Favorite.kt b/app/src/main/java/com/example/flowershopapp/ComposeUI/Favorite.kt new file mode 100644 index 0000000..a1b2ace --- /dev/null +++ b/app/src/main/java/com/example/flowershopapp/ComposeUI/Favorite.kt @@ -0,0 +1,160 @@ +package com.example.flowershopapp.ComposeUI + + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.foundation.layout.wrapContentWidth +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.CardElevation +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.layout.HorizontalAlignmentLine +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.navigation.NavController +import com.example.flowershopapp.Bouquet.Model.Bouquet +import com.example.flowershopapp.ComposeUI.Navigation.Screen +import com.example.flowershopapp.Bouquet.Model.getBouquets +import com.example.flowershopapp.R + +@Composable +fun Favorite(navController: NavController) { + val bouquets = getBouquets() + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text(text = "Избранное", fontFamily = FontFamily.Serif, fontSize = 40.sp,fontWeight = FontWeight.W600) + LazyColumn( + modifier = Modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + items(bouquets.chunked(2)) { bouquetPair -> + Row(modifier = Modifier + .padding(top = 20.dp, bottom = 20.dp) + .fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { + var k: Float = 0.5f + bouquetPair.forEach { bouquet -> + Box(modifier = Modifier + .fillMaxWidth(k) + .padding(start = 10.dp, end = 10.dp)) { + BouquetCard(bouquet = bouquet) } + k += 0.5f; + } + } + } + } + } +} + +@Composable +fun BouquetCard(bouquet: Bouquet) { + var showDialog by remember { mutableStateOf(false) } + var expandedName by remember { mutableStateOf(false) } + Card( + elevation = CardDefaults.cardElevation( + defaultElevation = 10.dp + ), + colors = CardDefaults.cardColors( + containerColor = Color.White + ) + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Box(contentAlignment = Alignment.TopEnd) { + Image( + painter = painterResource(id = bouquet.imageResourceId), + contentDescription = null, + modifier = Modifier + .height(180.dp) + .clip(shape = RoundedCornerShape(10.dp)), + contentScale = ContentScale.Crop + ) + Box(Modifier.clip(RoundedCornerShape(10.dp)).clickable { }) { + Icon( + painter = painterResource(id = R.drawable.icon_heart), + contentDescription = null, + modifier = Modifier + .size(40.dp) + .clip(shape = RoundedCornerShape(10.dp)) + ) + } + } + Spacer(modifier = Modifier.height(8.dp)) + if (expandedName) { + AlertDialog( + onDismissRequest = { expandedName = false }, + title = { + Text(text = bouquet.name, fontFamily = FontFamily.Serif, fontSize = 25.sp) + }, + confirmButton = { + Button( + onClick = { expandedName = false } + ) { + Text("Закрыть") + } + } + ) + } + Text(text = bouquet.name, + fontFamily = FontFamily.Serif, + fontSize = 20.sp, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + modifier = Modifier + .padding(start = 5.dp, end = 5.dp) + .clickable { expandedName = true }) + //Spacer(modifier = Modifier.height(1.dp)) + Text(text = "${bouquet.quantityOfFlowers} цветов", fontFamily = FontFamily.Serif, fontSize = 19.sp) + //Spacer(modifier = Modifier.height(8.dp)) + Text(text = "${bouquet.price}", fontFamily = FontFamily.Serif, fontSize = 19.sp) + Column(horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center) { + Button(modifier = Modifier.width(115.dp), shape = RoundedCornerShape(5.dp), onClick = { }, + colors = ButtonDefaults.buttonColors( + containerColor = colorResource(id = R.color.button) + )) { + Text("Купить") + } + Button(modifier = Modifier.width(115.dp), shape = RoundedCornerShape(5.dp), onClick = { }, + colors = ButtonDefaults.buttonColors( + containerColor = colorResource(id = R.color.button) + )) { + Text("В корзину") + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/flowershopapp/ComposeUI/Login.kt b/app/src/main/java/com/example/flowershopapp/ComposeUI/Login.kt new file mode 100644 index 0000000..bd83a4a --- /dev/null +++ b/app/src/main/java/com/example/flowershopapp/ComposeUI/Login.kt @@ -0,0 +1,111 @@ +package com.example.flowershopapp.ComposeUI + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonColors +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +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.res.colorResource +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.input.PasswordVisualTransformation +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.navigation.NavController +import com.example.flowershopapp.ComposeUI.Navigation.Screen +import com.example.flowershopapp.R + +@Composable +fun Login(navController: NavController) { + var username by remember { mutableStateOf("") } + var password by remember { mutableStateOf("") } + + Column( + modifier = Modifier + .fillMaxSize() + .background(color = colorResource(id = R.color.backgroundWindow)), + verticalArrangement = Arrangement.Top, horizontalAlignment = Alignment.CenterHorizontally + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .weight(1f), + horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically + ) { + Image(painter = painterResource(id = R.drawable.logo), contentDescription = "", Modifier.size(180.dp)) + } + Column( + modifier = Modifier + .fillMaxWidth() + .weight(2f) + .padding(bottom = 10.dp), + verticalArrangement = Arrangement.Top, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + text = stringResource(id = R.string.login_title), + fontSize = 26.sp, + fontWeight = FontWeight.Medium + ) + Spacer(modifier = Modifier.height(16.dp)) + TextField( + value = username, + onValueChange = { username = it }, + label = { Text("Имя пользователя") }, + colors = TextFieldDefaults.colors( + unfocusedContainerColor = colorResource(id = R.color.textFieldContainer), + focusedContainerColor = colorResource(id = R.color.textFieldContainer) + ) + ) + Spacer(modifier = Modifier.height(8.dp)) + TextField( + value = password, + onValueChange = { password = it }, + label = { Text("Пароль") }, + visualTransformation = PasswordVisualTransformation(), + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), + colors = TextFieldDefaults.colors( + unfocusedContainerColor = colorResource(id = R.color.textFieldContainer), + focusedContainerColor = colorResource(id = R.color.textFieldContainer) + ) + ) + Spacer(modifier = Modifier.height(16.dp)) + Button(shape = RoundedCornerShape(5.dp), onClick = { navController.navigate(Screen.BouquetCatalog.route)}, + colors = ButtonDefaults.buttonColors( + containerColor = colorResource(id = R.color.button) + )) { + Text("Вход") + } + Spacer(modifier = Modifier.height(16.dp)) + TextButton(onClick = { navController.navigate(Screen.Signup.route) }) { + Text(text = "У меня нет учетной записи") + } + } + } +} diff --git a/app/src/main/java/com/example/flowershopapp/ComposeUI/Navigation/MainNavbar.kt b/app/src/main/java/com/example/flowershopapp/ComposeUI/Navigation/MainNavbar.kt new file mode 100644 index 0000000..f726547 --- /dev/null +++ b/app/src/main/java/com/example/flowershopapp/ComposeUI/Navigation/MainNavbar.kt @@ -0,0 +1,322 @@ +package com.example.flowershopapp.ComposeUI.Navigation + +import android.annotation.SuppressLint +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.Crossfade +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.WindowInsets +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.wrapContentHeight +import androidx.compose.foundation.layout.wrapContentWidth +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material3.AlertDialogDefaults.containerColor +import androidx.compose.material3.AlertDialogDefaults.shape +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.CardElevation +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.NavigationBar +import androidx.compose.material3.NavigationBarDefaults +import androidx.compose.material3.NavigationBarItem +import androidx.compose.material3.NavigationBarItemColors +import androidx.compose.material3.NavigationBarItemDefaults +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.material3.contentColorFor +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.draw.clip +import androidx.compose.ui.draw.shadow +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.navigation.NavDestination +import androidx.navigation.NavDestination.Companion.hierarchy +import androidx.navigation.NavGraph.Companion.findStartDestination +import androidx.navigation.NavHostController +import androidx.navigation.NavType +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.currentBackStackEntryAsState +import androidx.navigation.compose.rememberNavController +import androidx.navigation.navArgument +import com.example.flowershopapp.Bouquet.ComposeUI.BouquetCatalog +import com.example.flowershopapp.Bouquet.ComposeUI.ShoppingCart +import com.example.flowershopapp.ComposeUI.Boot +import com.example.flowershopapp.ComposeUI.Favorite +import com.example.flowershopapp.ComposeUI.Login +import com.example.flowershopapp.ComposeUI.Profile +import com.example.flowershopapp.ComposeUI.Signup +import com.example.flowershopapp.R +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch + + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun Topbar( + navController: NavHostController, + currentScreen: Screen? +) { + var showImage by remember { mutableStateOf(true) } + TopAppBar( + + title = { + if (showImage) { + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically) { +// Column(horizontalAlignment = Alignment.Start, verticalArrangement = Arrangement.Bottom) { +// Text(stringResource(currentScreen?.resourceId ?: R.string.app_name), fontSize = 32.sp, fontWeight = FontWeight.Bold) +// } + Column(horizontalAlignment = Alignment.End) { + Image( + painter = painterResource(id = R.drawable.logo), + contentDescription = "ivi", + Modifier + .padding(end = 14.dp) + .size(180.dp) + ) + } + } + } + + }, + navigationIcon = { + if ( + navController.previousBackStackEntry != null + && (currentScreen == null || !currentScreen.showInBottomBar) + ) { + showImage = false + IconButton(onClick = { navController.navigateUp() }) { + Icon( + imageVector = Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = null, + tint = MaterialTheme.colorScheme.onPrimary + ) + } + } + else{ + showImage = true + } + } + ) +} + +@Composable +fun Navbar1( + navController: NavHostController, + currentDestination: NavDestination?, + modifier: Modifier = Modifier +) { + NavigationBar( + modifier = modifier + .height(55.dp) + .clip(RoundedCornerShape(20.dp)) + ) { + Screen.bottomBarItems.forEach { screen -> + NavigationBarItem( + colors = NavigationBarItemDefaults.colors( + indicatorColor = Color.LightGray + ), + modifier = modifier.padding(10.dp), + icon = { Icon(painter = painterResource(screen.icon!!), contentDescription = null) }, + //label = { Text(stringResource(screen.resourceId)) }, + selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true, + onClick = { + navController.navigate(screen.route) { + popUpTo(navController.graph.findStartDestination().id) { + saveState = true + } + launchSingleTop = true + restoreState = true + } + } + ) + } + } +} +@Composable +fun Navbar( + navController: NavHostController, + currentDestination: NavDestination?, + modifier: Modifier = Modifier +) { + Row( + modifier = Modifier + .fillMaxWidth() + .height(75.dp), + horizontalArrangement = Arrangement.SpaceEvenly, verticalAlignment = Alignment.CenterVertically + ) { + Screen.bottomBarItems.forEach { screen -> + val isSelected = currentDestination?.hierarchy?.any { it.route == screen.route } == true + val contentColor = + if (isSelected) MaterialTheme.colorScheme.primary else Color.Gray.copy(alpha = 0.8f) + Box( + contentAlignment = Alignment.Center, + modifier = Modifier + .clip(RoundedCornerShape(15.dp)) + .wrapContentHeight() + //.background(colorResource(id = R.color.backgroundNavBarColor)) + .clickable(onClick = { + navController.navigate(screen.route) { + popUpTo(navController.graph.findStartDestination().id) { + saveState = true + } + launchSingleTop = true + restoreState = true + } + }) + + ) { + Column( + modifier = Modifier + .padding(12.dp) + .wrapContentWidth(),//.background(Color.Red), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + screen.icon?.let { + Icon( + modifier = Modifier.size(30.dp), + painter = painterResource(screen.icon), + contentDescription = null, + tint = contentColor + ) + } +// AnimatedVisibility( +// visible = isSelected +// ) { + Text( + text = stringResource(screen.resourceId), + color = contentColor, + fontSize = 15.sp + ) +// } + } + } + } + } +} +//@Composable +//fun CustomBottomNavigationItem( +// item : Screen, +// isSelected : Boolean, +// onClick:()->Unit, +//) { +// val background = if (isSelected) MaterialTheme.colors.primary.copy(alpha = 0.1f) else Color.Transparent +// val contentColor = if (isSelected) MaterialTheme.colors.primary else MaterialTheme.colors.onBackground +// +// Box( +// modifier = Modifier +// .clip(CircleShape) +// .background(background) +// .clickable(onClick = onClick) +// +// ) { +// Row( +// modifier = Modifier +// .padding(12.dp), +// verticalAlignment = Alignment.CenterVertically, +// horizontalArrangement = Arrangement.spacedBy(4.dp) +// ) { +// Icon( +// imageVector = item.icon, +// contentDescription = null, +// tint = contentColor +// ) +// AnimatedVisibility( +// visible = isSelected +// ) { +// Text( +// text = item.title, +// color = contentColor +// ) +// } +// } +// } +//} + +@Composable +fun Navhost( + navController: NavHostController, + innerPadding: PaddingValues, + startScreen : String, + modifier: Modifier = Modifier +) { + NavHost( + navController, + startDestination = startScreen, + modifier.padding(innerPadding) + ) { + composable(Screen.Signup.route) { Signup(navController) } + composable(Screen.Login.route) { Login(navController) } + composable(Screen.Boot.route) { Boot(navController) } + composable(Screen.BouquetCatalog.route) { BouquetCatalog(navController) } + composable(Screen.Favorite.route) { Favorite(navController) } + composable(Screen.ShoppingCart.route) { ShoppingCart(navController) } + composable(Screen.Profile.route) { Profile() } +// composable(Screen.Profile.route) { Profile() } +// composable(Screen.Search.route) { Search(navController) } +// composable( +// Screen.MovieView.route, +// arguments = listOf(navArgument("id") { type = NavType.IntType }) +// ) { backStackEntry -> +// backStackEntry.arguments?.let { MovieView(it.getInt("id")) } +// } + } +} + +@SuppressLint("CoroutineCreationDuringComposition") +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun MainNavbar() { + val navController = rememberNavController() + val navBackStackEntry by navController.currentBackStackEntryAsState() + val currentDestination = navBackStackEntry?.destination + val currentScreen = currentDestination?.route?.let { Screen.getItem(it) } + + Scaffold(modifier = Modifier, + topBar = { + if (currentScreen == null || (currentScreen.showInBottomBar && currentScreen.showTopBarAndNavBar)) { + Topbar(navController, currentScreen) + } + }, + bottomBar = { + if (currentScreen == null || (currentScreen.showInBottomBar && currentScreen.showTopBarAndNavBar)) { + Navbar(navController, currentDestination) + //Navbar(navController, currentDestination) + } + } + ) { innerPadding -> + Navhost(navController, innerPadding, Screen.Boot.route) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/flowershopapp/ComposeUI/Navigation/Screen.kt b/app/src/main/java/com/example/flowershopapp/ComposeUI/Navigation/Screen.kt new file mode 100644 index 0000000..fbf66ff --- /dev/null +++ b/app/src/main/java/com/example/flowershopapp/ComposeUI/Navigation/Screen.kt @@ -0,0 +1,48 @@ +package com.example.flowershopapp.ComposeUI.Navigation + +import androidx.annotation.StringRes +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.AccountCircle +import androidx.compose.material.icons.filled.Favorite +import androidx.compose.material.icons.filled.Home +import androidx.compose.material.icons.filled.List +import androidx.compose.material.icons.filled.Search +import androidx.compose.material.icons.rounded.Favorite +import androidx.compose.material.icons.rounded.Home +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.res.painterResource +import com.example.flowershopapp.R + +enum class Screen ( + val route: String, + @StringRes val resourceId: Int, + val icon: Int?, + val showInBottomBar: Boolean = true, + val showTopBarAndNavBar: Boolean = true +){ + Signup("signup", R.string.signup_title, null, showInBottomBar = false, showTopBarAndNavBar = false), + Login("login", R.string.login_title, null, showInBottomBar = false, showTopBarAndNavBar = false), + Boot("boot", R.string.boot_title, null, showInBottomBar = false, showTopBarAndNavBar = false), + BouquetCatalog("bouquet-catalog", R.string.bouquet_catalog_title, R.drawable.icons8_home), + ShoppingCart("shopping-cart", R.string.shoppingCart_title, R.drawable.icons8_cart), + Profile("profile", R.string.profile_title, R.drawable.icons8_user), + Favorite("favorite", R.string.favorite_title, R.drawable.icons8_favorite); +// Search("search", R.string.search_title, Icons.Filled.Search), +// MovieView("movie-view/{id}", R.string.movie_view_title, Icons.Filled.List, showInBottomBar = false); + companion object { + val bottomBarItems = listOf( + BouquetCatalog, + Favorite, + ShoppingCart, + Profile +// Profile, +// Search, + ) + + fun getItem(route: String): Screen? { + val findRoute = route.split("/").first() + return values().find { value -> value.route.startsWith(findRoute) } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/flowershopapp/ComposeUI/Profile.kt b/app/src/main/java/com/example/flowershopapp/ComposeUI/Profile.kt new file mode 100644 index 0000000..864e3a0 --- /dev/null +++ b/app/src/main/java/com/example/flowershopapp/ComposeUI/Profile.kt @@ -0,0 +1,114 @@ +package com.example.flowershopapp.ComposeUI + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonColors +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +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.res.colorResource +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.navigation.NavController +import com.example.flowershopapp.ComposeUI.Navigation.Screen +import com.example.flowershopapp.R + + +@Composable +fun Profile(){ + var phoneNumber by remember { mutableStateOf("Имя пользователя") } + var FIO by remember { mutableStateOf("01-01-2000") } + var dateOfBirth by remember { mutableStateOf("Ваш номер телефона") } + + Column( + modifier = Modifier + .fillMaxSize() + .background(color = colorResource(id = R.color.backgroundWindow)), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .weight(2f) + .padding(bottom = 10.dp), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + text = "Профиль", + fontSize = 26.sp, + fontWeight = FontWeight.Medium + ) + Spacer(modifier = Modifier.height(16.dp)) + Image(painter = painterResource(id = R.drawable.icons8_profile), contentDescription = "", Modifier.size(140.dp)) + Spacer(modifier = Modifier.height(16.dp)) + TextField( + value = FIO, + onValueChange = { FIO = it }, + label = { Text("Имя пользователя") }, + colors = TextFieldDefaults.colors( + unfocusedContainerColor = colorResource(id = R.color.textFieldContainer), + focusedContainerColor = colorResource(id = R.color.textFieldContainer) + ) + ) + Spacer(modifier = Modifier.height(8.dp)) + TextField( + value = dateOfBirth, + onValueChange = { dateOfBirth = it }, + label = { Text("Дата рождения") }, + colors = TextFieldDefaults.colors( + unfocusedContainerColor = colorResource(id = R.color.textFieldContainer), + focusedContainerColor = colorResource(id = R.color.textFieldContainer) + ) + ) + Spacer(modifier = Modifier.height(8.dp)) + TextField( + value = phoneNumber, + onValueChange = { phoneNumber = it }, + label = { Text("Номер телефона") }, + colors = TextFieldDefaults.colors( + unfocusedContainerColor = colorResource(id = R.color.textFieldContainer), + focusedContainerColor = colorResource(id = R.color.textFieldContainer) + ) + ) + Spacer(modifier = Modifier.height(16.dp)) + Button( + shape = RoundedCornerShape(5.dp), + onClick = { /* Handle button click */ }, + colors = ButtonDefaults.buttonColors( + containerColor = colorResource(id = R.color.button) + ) + ) { + Text("Сохранить") + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/flowershopapp/ComposeUI/ShoppingСart.kt b/app/src/main/java/com/example/flowershopapp/ComposeUI/ShoppingСart.kt new file mode 100644 index 0000000..2de281f --- /dev/null +++ b/app/src/main/java/com/example/flowershopapp/ComposeUI/ShoppingСart.kt @@ -0,0 +1,173 @@ +package com.example.flowershopapp.Bouquet.ComposeUI + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +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.fillMaxHeight +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.layout.wrapContentHeight +import androidx.compose.foundation.layout.wrapContentWidth +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.CardElevation +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateListOf +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.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.navigation.NavController +import com.example.flowershopapp.Bouquet.Model.Bouquet +import com.example.flowershopapp.ComposeUI.Navigation.Screen +import com.example.flowershopapp.Bouquet.Model.getBouquets +import com.example.flowershopapp.Bouquet.Model.getBouquetsFromCart +import com.example.flowershopapp.R + +@Composable +fun ShoppingCart(navController: NavController) { + var totalCost by remember { mutableStateOf(getTotalCostOfItemsInCart()) } + val bouquets = remember { mutableStateListOf() } + bouquets.addAll(getBouquetsFromCart()) + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text(text = "Корзина", fontFamily = FontFamily.Serif, fontSize = 40.sp,fontWeight = FontWeight.W600) + LazyColumn( + modifier = Modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + items(bouquets) { bouquet -> + Row(modifier = Modifier.padding(top = 20.dp), horizontalArrangement = Arrangement.SpaceBetween) { + CartBouquetCard(bouquet = bouquet) { price -> + totalCost += price + + } + } + } + item{ + Text(text = "Общая сумма: $totalCost", fontSize = 25.sp, fontWeight = FontWeight.Bold) + Button( + modifier = Modifier.padding(bottom = 20.dp), + shape = RoundedCornerShape(5.dp), onClick = { }, + colors = ButtonDefaults.buttonColors( + containerColor = colorResource(id = R.color.button) + )) { + Text("Оформить") + } + } + } + } +} + +@Composable +fun CartBouquetCard(bouquet: Bouquet, onPriceChanged: (Int) -> Unit){ + var quantity by remember { mutableStateOf(1) } + Card( + modifier = Modifier + .padding(16.dp), + //.fillMaxWidth(), + elevation = CardDefaults.cardElevation( + defaultElevation = 10.dp + ), + colors = CardDefaults.cardColors( + containerColor = Color.White + ) + //modifier = Modifier.padding(start = 5.dp, end = 5.dp), + //horizontalAlignment = Alignment.CenterHorizontally + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Box(contentAlignment = Alignment.TopEnd) { + Image( + painter = painterResource(id = bouquet.imageResourceId), + contentDescription = null, + modifier = Modifier + .width(250.dp) + .height(250.dp) + .clip(shape = RoundedCornerShape(10.dp)), + contentScale = ContentScale.Crop + ) + Box( + Modifier + .clip(RoundedCornerShape(10.dp)) + .clickable { }) { + Icon( + painter = painterResource(id = R.drawable.icon_heart), + contentDescription = null, + modifier = Modifier + .size(40.dp) + .clip(shape = RoundedCornerShape(10.dp)) + ) + } + } + Spacer(modifier = Modifier.height(8.dp)) + Text(text = bouquet.name, fontFamily = FontFamily.Serif, fontSize = 25.sp) + //Spacer(modifier = Modifier.height(1.dp)) + Text(text = "${bouquet.quantityOfFlowers} цветов", fontFamily = FontFamily.Serif, fontSize = 19.sp) + //Spacer(modifier = Modifier.height(8.dp)) + Text(text = "${bouquet.price}", fontFamily = FontFamily.Serif, fontSize = 19.sp) + Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceAround, modifier = Modifier.height(50.dp)) { + Box(modifier = Modifier.fillMaxHeight(0.5f)){ + Icon( + painter = painterResource(id = R.drawable.icon_minus_cirlce), + contentDescription = "", + modifier = Modifier.clickable { + if (quantity >= 1) { + quantity-- + onPriceChanged(-bouquet.price) + } + } + ) + } + Box(){ + Text(text = "$quantity") + } + Box(modifier = Modifier.fillMaxHeight(0.5f)){ + Icon( + painter = painterResource(id = R.drawable.icon_add_circle), + contentDescription = "", + modifier = Modifier.clickable { + quantity++ + onPriceChanged(bouquet.price) + } + ) + } + } + } + } +} +fun getTotalCostOfItemsInCart(): Int { + val bouquetsInCart = getBouquetsFromCart() + var totalCost = 0 + for (bouquet in bouquetsInCart) { + totalCost += bouquet.price + } + return totalCost +} \ No newline at end of file diff --git a/app/src/main/java/com/example/flowershopapp/ComposeUI/Signup.kt b/app/src/main/java/com/example/flowershopapp/ComposeUI/Signup.kt new file mode 100644 index 0000000..173a488 --- /dev/null +++ b/app/src/main/java/com/example/flowershopapp/ComposeUI/Signup.kt @@ -0,0 +1,123 @@ +package com.example.flowershopapp.ComposeUI + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonColors +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +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.res.colorResource +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.input.PasswordVisualTransformation +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.navigation.NavController +import com.example.flowershopapp.ComposeUI.Navigation.Screen +import com.example.flowershopapp.R + +@Composable +fun Signup(navController: NavController) { + var username by remember { mutableStateOf("") } + var password by remember { mutableStateOf("") } + + Column( + modifier = Modifier + .fillMaxSize() + .background(color = colorResource(id = R.color.backgroundWindow)), + verticalArrangement = Arrangement.Top, horizontalAlignment = Alignment.CenterHorizontally + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .weight(1f), + horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically + ) { + Image(painter = painterResource(id = R.drawable.logo), contentDescription = "", Modifier.size(180.dp)) + } + Column( + modifier = Modifier + .fillMaxWidth() + .weight(2f) + .padding(bottom = 10.dp), + verticalArrangement = Arrangement.Top, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + text = stringResource(id = R.string.signup_title), + fontSize = 26.sp, + fontWeight = FontWeight.Medium + ) + Spacer(modifier = Modifier.height(16.dp)) + TextField( + value = username, + onValueChange = { username = it }, + label = { Text("Имя пользователя") }, + colors = TextFieldDefaults.colors( + unfocusedContainerColor = colorResource(id = R.color.textFieldContainer), + focusedContainerColor = colorResource(id = R.color.textFieldContainer) + ) + ) + Spacer(modifier = Modifier.height(8.dp)) + TextField( + value = password, + onValueChange = { password = it }, + label = { Text("Пароль") }, + visualTransformation = PasswordVisualTransformation(), + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), + colors = TextFieldDefaults.colors( + unfocusedContainerColor = colorResource(id = R.color.textFieldContainer), + focusedContainerColor = colorResource(id = R.color.textFieldContainer) + ) + ) + Spacer(modifier = Modifier.height(16.dp)) + TextField( + value = password, + onValueChange = { password = it }, + label = { Text("Подтвердите пароль") }, + visualTransformation = PasswordVisualTransformation(), + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), + colors = TextFieldDefaults.colors( + unfocusedContainerColor = colorResource(id = R.color.textFieldContainer), + focusedContainerColor = colorResource(id = R.color.textFieldContainer) + ) + ) + Spacer(modifier = Modifier.height(16.dp)) + Button(shape = RoundedCornerShape(5.dp), onClick = { navController.navigate(Screen.Login.route) }, + colors = ButtonDefaults.buttonColors( + containerColor = colorResource(id = R.color.button) + )) { + Text("Создать") + } + Spacer(modifier = Modifier.height(16.dp)) + TextButton(onClick = { navController.navigate(Screen.Login.route) }) { + Text(text = "У меня есть учетная запись") + } + } + } +} diff --git a/app/src/main/java/com/example/flowershopapp/MainActivity.kt b/app/src/main/java/com/example/flowershopapp/MainActivity.kt new file mode 100644 index 0000000..36be96d --- /dev/null +++ b/app/src/main/java/com/example/flowershopapp/MainActivity.kt @@ -0,0 +1,33 @@ +package com.example.flowershopapp + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.tooling.preview.Preview +import com.example.flowershopapp.ComposeUI.Navigation.MainNavbar +import com.example.flowershopapp.ui.theme.FlowerShopAppTheme + +class MainActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + FlowerShopAppTheme { + Surface( + modifier = Modifier + .fillMaxSize() + ) { + MainNavbar() + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/flowershopapp/ui/theme/Color.kt b/app/src/main/java/com/example/flowershopapp/ui/theme/Color.kt new file mode 100644 index 0000000..9e60f46 --- /dev/null +++ b/app/src/main/java/com/example/flowershopapp/ui/theme/Color.kt @@ -0,0 +1,13 @@ +package com.example.flowershopapp.ui.theme + +import androidx.compose.ui.graphics.Color + +val Purple80 = Color(0xFFD0BCFF) +val PurpleGrey80 = Color(0xFFCCC2DC) +val Pink80 = Color(0xFFEFB8C8) + +val Purple40 = Color(0xFF6650a4) +val PurpleGrey40 = Color(0xFF625b71) +val Pink40 = Color(0xFF7D5260) + +val Color1 = Color(0xFF2e3350); \ No newline at end of file diff --git a/app/src/main/java/com/example/flowershopapp/ui/theme/Theme.kt b/app/src/main/java/com/example/flowershopapp/ui/theme/Theme.kt new file mode 100644 index 0000000..e464480 --- /dev/null +++ b/app/src/main/java/com/example/flowershopapp/ui/theme/Theme.kt @@ -0,0 +1,74 @@ +package com.example.flowershopapp.ui.theme + +import android.annotation.SuppressLint +import android.app.Activity +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.SideEffect +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalView +import androidx.compose.ui.res.colorResource +import androidx.core.view.WindowCompat +import com.example.flowershopapp.R + +private val DarkColorScheme = darkColorScheme( + primary = Purple80, + secondary = PurpleGrey80, + tertiary = Pink80 +) + +private val LightColorScheme = lightColorScheme( + primary = Color1, + secondary = PurpleGrey40, + tertiary = Pink40, + + /* // Other default colors to override + background = Color(0xFFFFFBFE), + surface = Color(0xFFFFFBFE), + onPrimary = Color.White, + onSecondary = Color.White, + onTertiary = Color.White, + onBackground = Color(0xFF1C1B1F), + onSurface = Color(0xFF1C1B1F) + */ +) + +@Composable +fun FlowerShopAppTheme( + darkTheme: Boolean = false, + // Dynamic color is available on Android 12+ + dynamicColor: Boolean = false, + content: @Composable () -> Unit +) { + val colorScheme = when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } + + darkTheme -> DarkColorScheme + else -> LightColorScheme + } + val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as Activity).window + window.statusBarColor = colorScheme.primary.toArgb() + WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme + } + } + + MaterialTheme( + colorScheme = colorScheme, + typography = Typography, + content = content + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/example/flowershopapp/ui/theme/Type.kt b/app/src/main/java/com/example/flowershopapp/ui/theme/Type.kt new file mode 100644 index 0000000..a5a814f --- /dev/null +++ b/app/src/main/java/com/example/flowershopapp/ui/theme/Type.kt @@ -0,0 +1,34 @@ +package com.example.flowershopapp.ui.theme + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +// Set of Material typography styles to start with +val Typography = Typography( + bodyLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp + ) + /* Other default text styles to override + titleLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 22.sp, + lineHeight = 28.sp, + letterSpacing = 0.sp + ), + labelSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 11.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp + ) + */ +) \ No newline at end of file diff --git a/app/src/main/res/drawable/icon_add_circle.xml b/app/src/main/res/drawable/icon_add_circle.xml new file mode 100644 index 0000000..6d0e9c2 --- /dev/null +++ b/app/src/main/res/drawable/icon_add_circle.xml @@ -0,0 +1,14 @@ + + + + diff --git a/app/src/main/res/drawable/icon_heart.png b/app/src/main/res/drawable/icon_heart.png new file mode 100644 index 0000000..57dbd53 Binary files /dev/null and b/app/src/main/res/drawable/icon_heart.png differ diff --git a/app/src/main/res/drawable/icon_home.png b/app/src/main/res/drawable/icon_home.png new file mode 100644 index 0000000..776f35b Binary files /dev/null and b/app/src/main/res/drawable/icon_home.png differ diff --git a/app/src/main/res/drawable/icon_minus_cirlce.xml b/app/src/main/res/drawable/icon_minus_cirlce.xml new file mode 100644 index 0000000..9af63fe --- /dev/null +++ b/app/src/main/res/drawable/icon_minus_cirlce.xml @@ -0,0 +1,14 @@ + + + + diff --git a/app/src/main/res/drawable/icon_search.png b/app/src/main/res/drawable/icon_search.png new file mode 100644 index 0000000..f0b1a65 Binary files /dev/null and b/app/src/main/res/drawable/icon_search.png differ diff --git a/app/src/main/res/drawable/icon_user.png b/app/src/main/res/drawable/icon_user.png new file mode 100644 index 0000000..c7c485e Binary files /dev/null and b/app/src/main/res/drawable/icon_user.png differ diff --git a/app/src/main/res/drawable/icons8_cart.xml b/app/src/main/res/drawable/icons8_cart.xml new file mode 100644 index 0000000..fee09c3 --- /dev/null +++ b/app/src/main/res/drawable/icons8_cart.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/app/src/main/res/drawable/icons8_favorite.xml b/app/src/main/res/drawable/icons8_favorite.xml new file mode 100644 index 0000000..121a08d --- /dev/null +++ b/app/src/main/res/drawable/icons8_favorite.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/icons8_home.xml b/app/src/main/res/drawable/icons8_home.xml new file mode 100644 index 0000000..ca971fb --- /dev/null +++ b/app/src/main/res/drawable/icons8_home.xml @@ -0,0 +1,12 @@ + + + diff --git a/app/src/main/res/drawable/icons8_profile.xml b/app/src/main/res/drawable/icons8_profile.xml new file mode 100644 index 0000000..0d963ad --- /dev/null +++ b/app/src/main/res/drawable/icons8_profile.xml @@ -0,0 +1,12 @@ + + + diff --git a/app/src/main/res/drawable/icons8_user.xml b/app/src/main/res/drawable/icons8_user.xml new file mode 100644 index 0000000..d4ac0e8 --- /dev/null +++ b/app/src/main/res/drawable/icons8_user.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/image1.xml b/app/src/main/res/drawable/image1.xml new file mode 100644 index 0000000..0b4c72a --- /dev/null +++ b/app/src/main/res/drawable/image1.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/image_boot.jpg b/app/src/main/res/drawable/image_boot.jpg new file mode 100644 index 0000000..123689a Binary files /dev/null and b/app/src/main/res/drawable/image_boot.jpg differ diff --git a/app/src/main/res/drawable/image_bouquet1.png b/app/src/main/res/drawable/image_bouquet1.png new file mode 100644 index 0000000..60efa55 Binary files /dev/null and b/app/src/main/res/drawable/image_bouquet1.png differ diff --git a/app/src/main/res/drawable/image_bouquet2.png b/app/src/main/res/drawable/image_bouquet2.png new file mode 100644 index 0000000..2b8e6fd Binary files /dev/null and b/app/src/main/res/drawable/image_bouquet2.png differ diff --git a/app/src/main/res/drawable/image_bouquet4.png b/app/src/main/res/drawable/image_bouquet4.png new file mode 100644 index 0000000..2b4bec1 Binary files /dev/null and b/app/src/main/res/drawable/image_bouquet4.png differ diff --git a/app/src/main/res/drawable/image_bouquet5.png b/app/src/main/res/drawable/image_bouquet5.png new file mode 100644 index 0000000..58dff49 Binary files /dev/null and b/app/src/main/res/drawable/image_bouquet5.png differ diff --git a/app/src/main/res/drawable/image_bouquet6.png b/app/src/main/res/drawable/image_bouquet6.png new file mode 100644 index 0000000..1cdb385 Binary files /dev/null and b/app/src/main/res/drawable/image_bouquet6.png differ diff --git a/app/src/main/res/drawable/image_bouquet7.png b/app/src/main/res/drawable/image_bouquet7.png new file mode 100644 index 0000000..a8aba9d Binary files /dev/null and b/app/src/main/res/drawable/image_bouquet7.png differ diff --git a/app/src/main/res/drawable/image_bouquet8.png b/app/src/main/res/drawable/image_bouquet8.png new file mode 100644 index 0000000..e1cb279 Binary files /dev/null and b/app/src/main/res/drawable/image_bouquet8.png differ diff --git a/app/src/main/res/drawable/logo.jpg b/app/src/main/res/drawable/logo.jpg new file mode 100644 index 0000000..183ec09 Binary files /dev/null and b/app/src/main/res/drawable/logo.jpg differ diff --git a/app/src/main/res/drawable/logo1.png b/app/src/main/res/drawable/logo1.png new file mode 100644 index 0000000..0691144 Binary files /dev/null and b/app/src/main/res/drawable/logo1.png differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index f8c6127..482c5d5 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -7,4 +7,8 @@ #FF018786 #FF000000 #FFFFFFFF + #FBFBFB + #F6F6F6 + #2e3350 + #EEF0FF \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c9c82a5..f947494 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,6 +1,10 @@ - FlowerShop - Home - Dashboard - Notifications + FlowerShopApp + Регистрация + Вход + Загрузочный экран + Каталог + Избранное + Корзина + Профиль \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 1d432f7..8a397eb 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -1,16 +1,5 @@ - - - + + + +