This commit is contained in:
movavi 2023-11-14 09:13:26 +03:00
parent 5934717cb6
commit 6fb5b51fb8
57 changed files with 1008 additions and 652 deletions

1
.idea/.name Normal file
View File

@ -0,0 +1 @@
FlowerShopApp

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<runningDeviceTargetSelectedWithDropDown>
<Target>
<type value="RUNNING_DEVICE_TARGET" />
<deviceKey>
<Key>
<type value="SERIAL_NUMBER" />
<value value="RF8T107E6PV" />
</Key>
</deviceKey>
</Target>
</runningDeviceTargetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2023-10-30T15:01:39.013836900Z" />
</component>
</project>

View File

@ -3,30 +3,39 @@
<option name="myName" value="Project Default" />
<inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewApiLevelMustBeValid" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewFontScaleMustBeGreaterThanZero" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewMultipleParameterProviders" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
</profile>
</component>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.8.10" />
<option name="version" value="1.8.20" />
</component>
</project>

View File

@ -1,3 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="jbr-17" />
</GradleProjectSettings>
</option>
</component>
</project>

View File

@ -1,9 +0,0 @@
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

111
app/.idea/workspace.xml Normal file
View File

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="NONE" />
</component>
<component name="ChangeListManager">
<list default="true" id="540b4edc-b8de-442a-b540-e75c26fb8db3" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/../.gitignore" beforeDir="false" afterPath="$PROJECT_DIR$/../.gitignore" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../.idea/inspectionProfiles/Project_Default.xml" beforeDir="false" afterPath="$PROJECT_DIR$/../.idea/inspectionProfiles/Project_Default.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../.idea/kotlinc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/../.idea/kotlinc.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/../.idea/misc.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../.idea/vcs.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/.gitignore" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/gradle.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/vcs.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/build.gradle.kts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/proguard-rules.pro" beforeDir="false" afterPath="$PROJECT_DIR$/proguard-rules.pro" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/androidTest/java/com/example/flowershop/ExampleInstrumentedTest.kt" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/androidTest/java/com/example/flowershopapp/ExampleInstrumentedTest.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/androidTest/java/com/example/flowershopapp/ExampleInstrumentedTest.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/flowershop/MainActivity.kt" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/flowershop/ui/dashboard/DashboardFragment.kt" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/flowershop/ui/dashboard/DashboardViewModel.kt" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/flowershop/ui/home/HomeFragment.kt" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/flowershop/ui/home/HomeViewModel.kt" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/flowershop/ui/notifications/NotificationsFragment.kt" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/flowershop/ui/notifications/NotificationsViewModel.kt" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/flowershopapp/Bouquet/ComposeUI/BouquetCatalog.kt" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/flowershopapp/Bouquet/Model/Bouquet.kt" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/flowershopapp/ComposeUI/Favorite.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/example/flowershopapp/ComposeUI/Favorite.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/flowershopapp/ComposeUI/Login.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/example/flowershopapp/ComposeUI/Login.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/flowershopapp/ComposeUI/Navigation/MainNavbar.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/example/flowershopapp/ComposeUI/Navigation/MainNavbar.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/flowershopapp/ComposeUI/Navigation/Screen.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/example/flowershopapp/ComposeUI/Navigation/Screen.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/flowershopapp/ComposeUI/Profile.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/example/flowershopapp/ComposeUI/Profile.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/flowershopapp/ComposeUI/ShoppingСart.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/example/flowershopapp/ComposeUI/ShoppingСart.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/flowershopapp/MainActivity.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/example/flowershopapp/MainActivity.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/flowershopapp/ui/theme/Color.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/example/flowershopapp/ui/theme/Color.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/flowershopapp/ui/theme/Theme.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/example/flowershopapp/ui/theme/Theme.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/com/example/flowershopapp/ui/theme/Type.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/example/flowershopapp/ui/theme/Type.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/res/drawable/ic_dashboard_black_24dp.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/res/drawable/ic_home_black_24dp.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/res/drawable/ic_launcher_background.xml" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/res/drawable/ic_launcher_background.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/res/drawable/ic_launcher_foreground.xml" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/res/drawable/ic_launcher_foreground.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/res/drawable/ic_notifications_black_24dp.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/res/drawable/image1.xml" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/res/drawable/image1.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/res/layout/activity_main.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/res/layout/fragment_dashboard.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/res/layout/fragment_home.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/res/layout/fragment_notifications.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/res/menu/bottom_nav_menu.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/res/mipmap-anydpi-v26/ic_launcher.xml" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/res/mipmap-anydpi-v26/ic_launcher.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/res/navigation/mobile_navigation.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/res/values-night/themes.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/res/values/colors.xml" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/res/values/colors.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/res/values/dimens.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/res/values/strings.xml" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/res/values/strings.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/res/values/themes.xml" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/res/values/themes.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/res/xml/backup_rules.xml" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/res/xml/backup_rules.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/res/xml/data_extraction_rules.xml" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/res/xml/data_extraction_rules.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/test/java/com/example/flowershop/ExampleUnitTest.kt" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/test/java/com/example/flowershopapp/ExampleUnitTest.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/test/java/com/example/flowershopapp/ExampleUnitTest.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../build.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/../build.gradle.kts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../gradle.properties" beforeDir="false" afterPath="$PROJECT_DIR$/../gradle.properties" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../gradlew" beforeDir="false" afterPath="$PROJECT_DIR$/../gradlew" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../settings.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/../settings.gradle.kts" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="ExternalProjectsManager">
<system id="GRADLE">
<state>
<projects_view>
<tree_state>
<expand />
<select />
</tree_state>
</projects_view>
</state>
</system>
</component>
<component name="ProjectId" id="2Y9eG2i3BJIEW0JLnozi2HpYV82" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"RunOnceActivity.OpenProjectViewOnStart": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.cidr.known.project.marker": "true",
"android.gradle.sync.needed": "true",
"cidr.known.project.marker": "true",
"last_opened_file_path": "C:/Users/movavi/AndroidStudioProjects/FlowerShopAppGit"
}
}]]></component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="540b4edc-b8de-442a-b540-e75c26fb8db3" name="Changes" comment="" />
<created>1699942123160</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1699942123160</updated>
</task>
<servers />
</component>
</project>

View File

@ -1,6 +1,7 @@
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.devtools.ksp")
}
android {
@ -9,7 +10,7 @@ android {
defaultConfig {
applicationId = "com.example.flowershopapp"
minSdk = 25
minSdk = 26
targetSdk = 33
versionCode = 1
versionName = "1.0"
@ -30,17 +31,17 @@ android {
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "1.8"
jvmTarget = "17"
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.4.3"
kotlinCompilerExtensionVersion = "1.4.5"
}
packaging {
resources {
@ -48,21 +49,56 @@ android {
}
}
}
kotlin {
jvmToolchain(17)
}
dependencies {
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("org.mindrot:jbcrypt:0.4")
implementation ("io.coil-kt:coil-compose:2.5.0")
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.navigation:navigation-compose:2.7.4")
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
//implementation("androidx.compose.material3:material3")
implementation("com.google.android.engage:engage-core:1.3.1")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("androidx.compose.ui:ui-graphics-android:1.5.4")
//implementation("androidx.compose.material3:material3:1.1.2")
//implementation("androidx.compose.material3:material3-desktop:1.2.0-alpha10")
//implementation("androidx.compose.material3:material3-android:1.2.0-alpha10")
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")
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
// UI
implementation("androidx.activity:activity-compose:1.8.0")
implementation(platform("androidx.compose:compose-bom:2023.10.01"))
implementation("androidx.navigation:navigation-compose:2.7.4")
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")
// Room
val room_version = "2.5.2"
implementation("androidx.room:room-runtime:$room_version")
annotationProcessor("androidx.room:room-compiler:$room_version")
ksp("androidx.room:room-compiler:$room_version")
implementation("androidx.room:room-ktx:$room_version")
implementation("androidx.room:room-paging:$room_version")
// Tests
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")

View File

@ -1,24 +0,0 @@
package com.example.flowershop
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.flowershop", appContext.packageName)
}
}

View File

@ -1,35 +0,0 @@
package com.example.flowershop
import android.os.Bundle
import com.google.android.material.bottomnavigation.BottomNavigationView
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.example.flowershop.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val navView: BottomNavigationView = binding.navView
val navController = findNavController(R.id.nav_host_fragment_activity_main)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
val appBarConfiguration = AppBarConfiguration(
setOf(
R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications
)
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
}

View File

@ -1,42 +0,0 @@
package com.example.flowershop.ui.dashboard
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.example.flowershop.databinding.FragmentDashboardBinding
class DashboardFragment : Fragment() {
private var _binding: FragmentDashboardBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val dashboardViewModel =
ViewModelProvider(this).get(DashboardViewModel::class.java)
_binding = FragmentDashboardBinding.inflate(inflater, container, false)
val root: View = binding.root
val textView: TextView = binding.textDashboard
dashboardViewModel.text.observe(viewLifecycleOwner) {
textView.text = it
}
return root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@ -1,13 +0,0 @@
package com.example.flowershop.ui.dashboard
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class DashboardViewModel : ViewModel() {
private val _text = MutableLiveData<String>().apply {
value = "This is dashboard Fragment"
}
val text: LiveData<String> = _text
}

View File

@ -1,42 +0,0 @@
package com.example.flowershop.ui.home
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.example.flowershop.databinding.FragmentHomeBinding
class HomeFragment : Fragment() {
private var _binding: FragmentHomeBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val homeViewModel =
ViewModelProvider(this).get(HomeViewModel::class.java)
_binding = FragmentHomeBinding.inflate(inflater, container, false)
val root: View = binding.root
val textView: TextView = binding.textHome
homeViewModel.text.observe(viewLifecycleOwner) {
textView.text = it
}
return root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@ -1,13 +0,0 @@
package com.example.flowershop.ui.home
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class HomeViewModel : ViewModel() {
private val _text = MutableLiveData<String>().apply {
value = "This is home Fragment"
}
val text: LiveData<String> = _text
}

View File

@ -1,42 +0,0 @@
package com.example.flowershop.ui.notifications
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.example.flowershop.databinding.FragmentNotificationsBinding
class NotificationsFragment : Fragment() {
private var _binding: FragmentNotificationsBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val notificationsViewModel =
ViewModelProvider(this).get(NotificationsViewModel::class.java)
_binding = FragmentNotificationsBinding.inflate(inflater, container, false)
val root: View = binding.root
val textView: TextView = binding.textNotifications
notificationsViewModel.text.observe(viewLifecycleOwner) {
textView.text = it
}
return root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@ -1,13 +0,0 @@
package com.example.flowershop.ui.notifications
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class NotificationsViewModel : ViewModel() {
private val _text = MutableLiveData<String>().apply {
value = "This is notifications Fragment"
}
val text: LiveData<String> = _text
}

View File

@ -1,31 +0,0 @@
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<Bouquet> {
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<Bouquet> {
return listOf(
Bouquet(1, "Нежная Роза", 12, 2500, R.drawable.image_bouquet1, 1),
Bouquet(2, "Лилия Элегия", 15, 2900, R.drawable.image_bouquet2, 2),
)
}

View File

@ -1,8 +1,8 @@
package com.example.flowershopapp.ComposeUI
import android.graphics.BitmapFactory
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
@ -15,10 +15,7 @@ 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
@ -26,12 +23,12 @@ 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.LaunchedEffect
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
@ -39,8 +36,9 @@ 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.graphics.asImageBitmap
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.HorizontalAlignmentLine
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontFamily
@ -49,14 +47,21 @@ 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.Database.AppDatabase
import com.example.flowershopapp.Entities.Model.Bouquet
import com.example.flowershopapp.Entities.Model.CartModel
import com.example.flowershopapp.Entities.Model.FavoriteModel
import com.example.flowershopapp.R
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@Composable
fun Favorite(navController: NavController) {
val bouquets = getBouquets()
var bouquets by remember { mutableStateOf(FavoriteModel.bouquets.toList()) }
val removeBouquet: (List<Bouquet>) -> Unit = { bouquetsNew ->
bouquets = bouquetsNew
}
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(text = "Избранное", fontFamily = FontFamily.Serif, fontSize = 40.sp,fontWeight = FontWeight.W600)
LazyColumn(
@ -72,7 +77,7 @@ fun Favorite(navController: NavController) {
Box(modifier = Modifier
.fillMaxWidth(k)
.padding(start = 10.dp, end = 10.dp)) {
BouquetCard(bouquet = bouquet) }
BouquetCard(bouquet = bouquet, onRemove = removeBouquet) }
k += 0.5f;
}
}
@ -82,7 +87,7 @@ fun Favorite(navController: NavController) {
}
@Composable
fun BouquetCard(bouquet: Bouquet) {
fun BouquetCard(bouquet: Bouquet, onRemove: (List<Bouquet>) -> Unit) {
var showDialog by remember { mutableStateOf(false) }
var expandedName by remember { mutableStateOf(false) }
Card(
@ -95,8 +100,10 @@ fun BouquetCard(bouquet: Bouquet) {
) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Box(contentAlignment = Alignment.TopEnd) {
val decodedBitmap = BitmapFactory.decodeByteArray(bouquet.image, 0, bouquet.image!!.size)
val imageBitmap = decodedBitmap.asImageBitmap()
Image(
painter = painterResource(id = bouquet.imageResourceId),
bitmap = imageBitmap,
contentDescription = null,
modifier = Modifier
.height(180.dp)
@ -110,6 +117,7 @@ fun BouquetCard(bouquet: Bouquet) {
modifier = Modifier
.size(40.dp)
.clip(shape = RoundedCornerShape(10.dp))
.clickable {onRemove(FavoriteModel.removeBouquets(bouquet)) }
)
}
}
@ -148,7 +156,7 @@ fun BouquetCard(bouquet: Bouquet) {
)) {
Text("Купить")
}
Button(modifier = Modifier.width(115.dp), shape = RoundedCornerShape(5.dp), onClick = { },
Button(modifier = Modifier.width(115.dp), shape = RoundedCornerShape(5.dp), onClick = { CartModel.addBouquet(bouquet) },
colors = ButtonDefaults.buttonColors(
containerColor = colorResource(id = R.color.button)
)) {

View File

@ -29,6 +29,7 @@ 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.platform.LocalContext
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
@ -37,14 +38,46 @@ 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.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import com.example.flowershopapp.ComposeUI.Navigation.Screen
import com.example.flowershopapp.Database.AppDatabase
import com.example.flowershopapp.Entities.Model.AuthModel
import com.example.flowershopapp.Entities.Model.User
import com.example.flowershopapp.R
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@Composable
fun Login(navController: NavController) {
var username by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
val context = LocalContext.current
val authModel: AuthModel = viewModel()
val database = remember { AppDatabase.getInstance(context) }
fun onAuthenticationSuccess(user: User){
authModel.setAuthenticatedUser(user)
navController.navigate(Screen.BouquetCatalog.route)
}
val coroutineScope = CoroutineScope(Dispatchers.Main)
fun login(){
coroutineScope.launch(Dispatchers.IO) {
val user = withContext(Dispatchers.IO) {
database.userDao().getUser(username)
}
withContext(Dispatchers.Main) {
if (user != null && user.password == password) {
onAuthenticationSuccess(user)
}
}
}
}
Column(
modifier = Modifier
@ -96,7 +129,7 @@ fun Login(navController: NavController) {
)
)
Spacer(modifier = Modifier.height(16.dp))
Button(shape = RoundedCornerShape(5.dp), onClick = { navController.navigate(Screen.BouquetCatalog.route)},
Button(shape = RoundedCornerShape(5.dp), onClick = { login() },
colors = ButtonDefaults.buttonColors(
containerColor = colorResource(id = R.color.button)
)) {

View File

@ -1,18 +1,13 @@
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
@ -21,41 +16,26 @@ 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.material.icons.filled.ArrowBack
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
@ -70,16 +50,15 @@ 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.Entities.ComposeUI.BouquetCatalog
import com.example.flowershopapp.Entities.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.Orders
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)
@ -118,7 +97,7 @@ fun Topbar(
showImage = false
IconButton(onClick = { navController.navigateUp() }) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
imageVector = Icons.Filled.ArrowBack,
contentDescription = null,
tint = MaterialTheme.colorScheme.onPrimary
)
@ -283,7 +262,12 @@ fun Navhost(
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(navController) }
composable(
Screen.Orders.route
) { backStackEntry ->
backStackEntry.arguments?.let { Orders() }
}
// composable(Screen.Profile.route) { Profile() }
// composable(Screen.Search.route) { Search(navController) }
// composable(
@ -317,6 +301,6 @@ fun MainNavbar() {
}
}
) { innerPadding ->
Navhost(navController, innerPadding, Screen.Boot.route)
Navhost(navController, innerPadding, Screen.Login.route)
}
}

View File

@ -24,6 +24,7 @@ enum class Screen (
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),
Orders("orders", 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),
@ -36,8 +37,6 @@ enum class Screen (
Favorite,
ShoppingCart,
Profile
// Profile,
// Search,
)
fun getItem(route: String): Screen? {

View File

@ -0,0 +1,61 @@
package com.example.flowershopapp.ComposeUI
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Divider
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.example.flowershopapp.Database.AppDatabase
import com.example.flowershopapp.Entities.Model.AuthModel
import com.example.flowershopapp.Entities.Model.Bouquet
import com.example.flowershopapp.Entities.Model.Order
import com.example.flowershopapp.Entities.Model.UsersWithOrders
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@Composable
fun Orders() {
val context = LocalContext.current
val (userWithOrders, setUserWithOrders) = remember { mutableStateOf<UsersWithOrders?>(null) }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
setUserWithOrders(AppDatabase.getInstance(context).userDao().getUserWithOrders(AuthModel.currentUser.userName))
}
}
LazyColumn {
var orders = userWithOrders?.orders
orders?.let{
items(orders) { order ->
OrderItem(order = order)
//Divider(color = Color.Red, thickness = 1.dp)
}
}
}
}
@Composable
fun OrderItem(order: Order) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(text = "ID: ${order.orderId}", fontWeight = FontWeight.Bold)
Text(text = "Date: ${order.date}")
Text(text = "Sum: ${order.sum}")
}
}

View File

@ -22,6 +22,7 @@ import androidx.compose.material3.TextButton
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
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
@ -29,6 +30,7 @@ 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.platform.LocalContext
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
@ -37,14 +39,32 @@ 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.Database.AppDatabase
import com.example.flowershopapp.Entities.Model.AuthModel
import com.example.flowershopapp.Entities.Model.User
import com.example.flowershopapp.R
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@Composable
fun Profile(){
var phoneNumber by remember { mutableStateOf("Имя пользователя") }
var FIO by remember { mutableStateOf("01-01-2000") }
var dateOfBirth by remember { mutableStateOf("Ваш номер телефона") }
fun Profile(navController: NavController){
var phoneNumber by remember { mutableStateOf("Ваш номер телефона") }
var userName by remember { mutableStateOf("Имя пользователя") }
var dateOfBirth by remember { mutableStateOf("01-01-2000") }
val (user, setUser) = remember { mutableStateOf<User?>(null) }
val context = LocalContext.current
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
val currentUser = AuthModel.currentUser
if (currentUser != null) {
setUser(AppDatabase.getInstance(context).userDao().getUser(currentUser.userName))
}
}
}
Column(
modifier = Modifier
@ -53,60 +73,62 @@ fun Profile(){
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)
)
user?.let{
Column(
modifier = Modifier
.fillMaxWidth()
.weight(2f)
.padding(bottom = 10.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("Сохранить")
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 = user.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 = user.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 = user.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 = { navController.navigate(Screen.Orders.route) },
colors = ButtonDefaults.buttonColors(
containerColor = colorResource(id = R.color.button)
)
) {
Text("История заказов")
}
}
}
}

View File

@ -1,7 +1,7 @@
package com.example.flowershopapp.Bouquet.ComposeUI
package com.example.flowershopapp.Entities.ComposeUI
import android.graphics.BitmapFactory
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
@ -10,26 +10,21 @@ 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.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
@ -39,6 +34,7 @@ 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.graphics.asImageBitmap
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
@ -47,17 +43,20 @@ 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.Entities.Model.Bouquet
import com.example.flowershopapp.Entities.Model.CartModel
import com.example.flowershopapp.Entities.Model.FavoriteModel
import com.example.flowershopapp.R
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@Composable
fun ShoppingCart(navController: NavController) {
var totalCost by remember { mutableStateOf(getTotalCostOfItemsInCart()) }
val bouquets = remember { mutableStateListOf<Bouquet>() }
bouquets.addAll(getBouquetsFromCart())
var bouquets by remember { mutableStateOf(CartModel.bouquets.toList()) }
val removeBouquet: (List<Bouquet>) -> Unit = { bouquetsNew ->
bouquets = bouquetsNew
}
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(text = "Корзина", fontFamily = FontFamily.Serif, fontSize = 40.sp,fontWeight = FontWeight.W600)
LazyColumn(
@ -66,10 +65,7 @@ fun ShoppingCart(navController: NavController) {
) {
items(bouquets) { bouquet ->
Row(modifier = Modifier.padding(top = 20.dp), horizontalArrangement = Arrangement.SpaceBetween) {
CartBouquetCard(bouquet = bouquet) { price ->
totalCost += price
}
CartBouquetCard(bouquet = bouquet, onPriceChanged = { price -> totalCost += price }, onRemove = removeBouquet)
}
}
item{
@ -88,7 +84,7 @@ fun ShoppingCart(navController: NavController) {
}
@Composable
fun CartBouquetCard(bouquet: Bouquet, onPriceChanged: (Int) -> Unit){
fun CartBouquetCard(bouquet: Bouquet, onPriceChanged: (Int) -> Unit, onRemove: (List<Bouquet>) -> Unit){
var quantity by remember { mutableStateOf(1) }
Card(
modifier = Modifier
@ -105,8 +101,10 @@ fun CartBouquetCard(bouquet: Bouquet, onPriceChanged: (Int) -> Unit){
) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Box(contentAlignment = Alignment.TopEnd) {
val decodedBitmap = BitmapFactory.decodeByteArray(bouquet.image, 0, bouquet.image!!.size)
val imageBitmap = decodedBitmap.asImageBitmap()
Image(
painter = painterResource(id = bouquet.imageResourceId),
bitmap = imageBitmap,
contentDescription = null,
modifier = Modifier
.width(250.dp)
@ -143,6 +141,9 @@ fun CartBouquetCard(bouquet: Bouquet, onPriceChanged: (Int) -> Unit){
quantity--
onPriceChanged(-bouquet.price)
}
if (quantity == 0){
onRemove(CartModel.removeBouquets(bouquet))
}
}
)
}
@ -164,7 +165,7 @@ fun CartBouquetCard(bouquet: Bouquet, onPriceChanged: (Int) -> Unit){
}
}
fun getTotalCostOfItemsInCart(): Int {
val bouquetsInCart = getBouquetsFromCart()
val bouquetsInCart = CartModel.bouquets
var totalCost = 0
for (bouquet in bouquetsInCart) {
totalCost += bouquet.price

View File

@ -0,0 +1,130 @@
package com.example.flowershopapp.Database
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import androidx.sqlite.db.SupportSQLiteDatabase
import com.example.flowershopapp.Entities.Converters
import com.example.flowershopapp.Entities.DAO.BouquetDAO
import com.example.flowershopapp.Entities.DAO.OrderDAO
import com.example.flowershopapp.Entities.DAO.OrdersWithBouquet
import com.example.flowershopapp.Entities.DAO.UserDAO
import com.example.flowershopapp.Entities.DAO.UsersWithOrders
import com.example.flowershopapp.Entities.Model.Bouquet
import com.example.flowershopapp.Entities.Model.Order
import com.example.flowershopapp.Entities.Model.OrderBouquetCrossRef
import com.example.flowershopapp.Entities.Model.User
import com.example.flowershopapp.Entities.Model.UserOrderCrossRef
import com.example.flowershopapp.R
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@Database(entities = [User::class, Order::class, Bouquet::class, UserOrderCrossRef::class, OrderBouquetCrossRef::class], version = 5, exportSchema = false)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDAO
abstract fun bouquetDao(): BouquetDAO
abstract fun orderDao(): OrderDAO
abstract fun orderWithBouquetsDao(): OrdersWithBouquet
abstract fun userWithOrders(): UsersWithOrders
companion object {
private const val DB_NAME: String = "flowershop-db"
val converters = Converters()
@Volatile
private var INSTANCE: AppDatabase? = null
private suspend fun populateDatabase(appContext: Context) {
INSTANCE?.let { database ->
val order1 = Order("12.06.2023", 15000)
val order2 = Order("07.08.2023", 7800)
val order3 = Order("07.08.2022", 252)
val order4 = Order("23.04.2021", 5554)
val order5 = Order("14.12.2022", 23552)
val orderDao: OrderDAO = database.orderDao()
orderDao.insert(order1)
orderDao.insert(order2)
orderDao.insert(order3)
orderDao.insert(order4)
orderDao.insert(order5)
val user1 = User(1, "Alina", "23.09.2005", "89020990981", "123")
val user2 = User(2, "2", "2", "2", "2")
val userDao: UserDAO = database.userDao()
userDao.insert(user1)
userDao.insert(user2)
var image1 = converters.imageResourceToByteArray(appContext, R.drawable.image_bouquet1)
var image2 = converters.imageResourceToByteArray(appContext, R.drawable.image_bouquet2)
val bouquets = listOf(
Bouquet(
1,
"Bouquet1",
5,
3432,
image1,
),
Bouquet(
2,
"Bouquet2",
9,
2342,
image2,
)
)
val bouquetDao: BouquetDAO = database.bouquetDao()
bouquets.forEach { movie ->
bouquetDao.insert(movie)
}
val usersDao: UsersWithOrders = database.userWithOrders()
val usersWithOrders = listOf(
UserOrderCrossRef(userId = 1, orderId = 1), // Movie A with Action
UserOrderCrossRef(userId = 2, orderId = 2), // Movie A with Comedy
UserOrderCrossRef(userId = 1, orderId = 3), // Movie A with Comedy
UserOrderCrossRef(userId = 2, orderId = 4), // Movie A with Comedy
UserOrderCrossRef(userId = 1, orderId = 5), // Movie A with Comedy
)
usersWithOrders.forEach { usersDao.insert(it) }
val ordersDao: OrdersWithBouquet = database.orderWithBouquetsDao()
val orderWithBouquets = listOf(
OrderBouquetCrossRef(bouquetId = 1, orderId = 1), // Movie A with Action
OrderBouquetCrossRef(bouquetId = 2, orderId = 2), // Movie A with Comedy
OrderBouquetCrossRef(bouquetId = 3, orderId = 1), // Movie A with Comedy
OrderBouquetCrossRef(bouquetId = 4, orderId = 2), // Movie A with Comedy
OrderBouquetCrossRef(bouquetId = 5, orderId = 2), // Movie A with Comedy
)
orderWithBouquets.forEach { ordersDao.insert(it) }
}
}
fun getInstance(appContext: Context): AppDatabase {
return INSTANCE ?: synchronized(this) {
Room.databaseBuilder(
appContext,
AppDatabase::class.java,
DB_NAME
)
.addCallback(object : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
CoroutineScope(Dispatchers.IO).launch {
populateDatabase(appContext)
}
}
})
.build()
.also { INSTANCE = it }
}
}
}
}

View File

@ -1,7 +1,7 @@
package com.example.flowershopapp.Bouquet.ComposeUI
package com.example.flowershopapp.Entities.ComposeUI
import android.graphics.BitmapFactory
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
@ -9,30 +9,30 @@ 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.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
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.graphics.asImageBitmap
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontFamily
@ -40,14 +40,26 @@ 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.Database.AppDatabase
import com.example.flowershopapp.Entities.Model.Bouquet
import com.example.flowershopapp.Entities.Model.CartModel
import com.example.flowershopapp.Entities.Model.FavoriteModel
import com.example.flowershopapp.R
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@Composable
fun BouquetCatalog(navController: NavController) {
val bouquets = getBouquets()
val context = LocalContext.current
val bouquets = remember { mutableStateListOf<Bouquet>() }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
AppDatabase.getInstance(context).bouquetDao().getAll().collect { data ->
bouquets.clear()
bouquets.addAll(data)
}
}
}
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(text = "Каталог букетов", fontFamily = FontFamily.Serif, fontSize = 40.sp,fontWeight = FontWeight.W600)
@ -78,15 +90,19 @@ fun BouquetCard(bouquet: Bouquet) {
) {
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
)
bouquet.image?.let { imageData ->
val decodedBitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.size)
val imageBitmap = decodedBitmap.asImageBitmap()
Image(
bitmap = imageBitmap,
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),
@ -94,6 +110,7 @@ fun BouquetCard(bouquet: Bouquet) {
modifier = Modifier
.size(40.dp)
.clip(shape = RoundedCornerShape(10.dp))
.clickable { FavoriteModel.addBouquet(bouquet) }
)
}
}
@ -113,7 +130,7 @@ fun BouquetCard(bouquet: Bouquet) {
}
Spacer(modifier = Modifier.width(8.dp))
Button(modifier = Modifier
.width(115.dp), shape = RoundedCornerShape(8.dp), onClick = { },
.width(115.dp), shape = RoundedCornerShape(8.dp), onClick = { CartModel.addBouquet(bouquet) },
colors = ButtonDefaults.buttonColors(
containerColor = colorResource(id = R.color.button)
)) {

View File

@ -0,0 +1,38 @@
package com.example.flowershopapp.Entities
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.util.Base64
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asAndroidBitmap
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.imageResource
import androidx.room.TypeConverter
import java.io.ByteArrayOutputStream
import java.io.File
import java.sql.Blob
class Converters {
@TypeConverter
fun fromByteArray(byteArray: ByteArray): String {
return byteArray.toString(Charsets.ISO_8859_1)
}
@TypeConverter
fun toByteArray(value: String): ByteArray {
return value.toByteArray(Charsets.ISO_8859_1)
}
fun imageResourceToByteArray(context: Context, resId: Int): ByteArray {
val bitmap = BitmapFactory.decodeResource(context.resources, resId)
val stream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream)
return stream.toByteArray()
}
fun bitmapToByteArray(bitmap: Bitmap): ByteArray {
val stream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream)
return stream.toByteArray()
}
}

View File

@ -0,0 +1,30 @@
package com.example.flowershopapp.Entities.DAO
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.flowershopapp.Entities.Model.Bouquet
import com.example.flowershopapp.Entities.Model.Order
import com.example.flowershopapp.Entities.Model.OrdersWithBouquets
import kotlinx.coroutines.flow.Flow
@Dao
interface BouquetDAO {
@Query("select * from bouquets")
fun getAll(): Flow<List<Bouquet>>
@Query("select * from bouquets where bouquetId = :id")
fun getBouquet(id: Int): Bouquet
@Insert
suspend fun insert(bouquet: Bouquet)
@Update
suspend fun update(bouquet: Bouquet)
@Delete
suspend fun delete(bouquet: Bouquet)
}

View File

@ -0,0 +1,31 @@
package com.example.flowershopapp.Entities.DAO
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.flowershopapp.Entities.Model.Order
import com.example.flowershopapp.Entities.Model.OrdersWithBouquets
import kotlinx.coroutines.flow.Flow
@Dao
interface OrderDAO {
@Query("select * from orders")
fun getAll(): List<Order>
@Query("select * from orders")
fun getOrdersWithBouquet(): Flow<List<OrdersWithBouquets>>
@Query("select * from orders where orderId = :id")
fun getOrderWithBouquet(id: Int): OrdersWithBouquets
@Insert
suspend fun insert(order: Order)
@Update
suspend fun update(order: Order)
@Delete
suspend fun delete(order: Order)
}

View File

@ -0,0 +1,21 @@
package com.example.flowershopapp.Entities.DAO
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Update
import com.example.flowershopapp.Entities.Model.OrderBouquetCrossRef
import com.example.flowershopapp.Entities.Model.OrdersWithBouquets
import com.example.flowershopapp.Entities.Model.UsersWithOrders
@Dao
interface OrdersWithBouquet {
@Insert
suspend fun insert(order: OrderBouquetCrossRef)
@Update
suspend fun update(order: OrderBouquetCrossRef)
@Delete
suspend fun delete(order: OrderBouquetCrossRef)
}

View File

@ -0,0 +1,35 @@
package com.example.flowershopapp.Entities.DAO
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.flowershopapp.Entities.Model.OrdersWithBouquets
import com.example.flowershopapp.Entities.Model.User
import com.example.flowershopapp.Entities.Model.UsersWithOrders
import kotlinx.coroutines.flow.Flow
@Dao
interface UserDAO {
@Query("select * from users")
fun getAll(): List<User>
@Query("select * from users where name = :userName")
fun getUser(userName: String): User
@Query("select * from users where name = :userName")
fun getUserWithOrders(userName: String): UsersWithOrders
@Query("select * from users")
fun getUsersWithOrders(): Flow<List<UsersWithOrders>>
@Insert
suspend fun insert(user: User)
@Update
suspend fun update(user: User)
@Delete
suspend fun delete(user: User)
}

View File

@ -0,0 +1,20 @@
package com.example.flowershopapp.Entities.DAO
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Update
import com.example.flowershopapp.Entities.Model.UserOrderCrossRef
import com.example.flowershopapp.Entities.Model.UsersWithOrders
@Dao
interface UsersWithOrders {
@Insert
suspend fun insert(user: UserOrderCrossRef)
@Update
suspend fun update(user: UserOrderCrossRef)
@Delete
suspend fun delete(user: UserOrderCrossRef)
}

View File

@ -0,0 +1,14 @@
package com.example.flowershopapp.Entities.Model
import androidx.lifecycle.ViewModel
class AuthModel : ViewModel() {
companion object {
lateinit var currentUser: User
private set
}
fun setAuthenticatedUser(user: User?) {
currentUser = user ?: throw IllegalArgumentException("User cannot be null")
}
}

View File

@ -0,0 +1,42 @@
package com.example.flowershopapp.Entities.Model
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Ignore
import androidx.room.PrimaryKey
@Entity(tableName = "bouquets")
data class Bouquet(
@PrimaryKey(autoGenerate = true)
val bouquetId: Int?,
@ColumnInfo(name = "name")
val name: String,
@ColumnInfo(name = "quantityOfFlowers")
val quantityOfFlowers: Int,
@ColumnInfo(name = "duration")
val price: Int,
@ColumnInfo(typeAffinity = ColumnInfo.BLOB, name = "image")
val image: ByteArray? = null,
) {
@Ignore
constructor(
name: String,
quantityOfFlowers: Int,
price: Int,
image: ByteArray,
) : this(null, name, quantityOfFlowers, price, image)
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Bouquet
if (bouquetId != other.bouquetId) return false
return true
}
override fun hashCode(): Int {
return bouquetId ?: -1
}
}

View File

@ -0,0 +1,33 @@
package com.example.flowershopapp.Entities.Model
import androidx.lifecycle.ViewModel
class CartModel : ViewModel() {
companion object {
private var bouquetsList = mutableListOf<Bouquet>()
val bouquets: List<Bouquet>
get() = bouquetsList.toList()
fun addBouquet(bouquet: Bouquet) {
bouquetsList.add(bouquet)
}
fun addBouquets(vararg bouquets: Bouquet) {
bouquetsList.addAll(bouquets)
}
fun removeBouquets(bouquetRemove: Bouquet) : List<Bouquet> {
var list : MutableList<Bouquet> = mutableListOf()
bouquetsList.forEach{ bouquet ->
if (bouquet.bouquetId != bouquetRemove.bouquetId) list.add(bouquet)
}
bouquetsList = list
return bouquetsList
}
fun clearBouquets() {
bouquetsList.clear()
}
}
}

View File

@ -0,0 +1,33 @@
package com.example.flowershopapp.Entities.Model
import androidx.lifecycle.ViewModel
class FavoriteModel : ViewModel() {
companion object {
private var favoriteList = mutableListOf<Bouquet>()
val bouquets: List<Bouquet>
get() = favoriteList.toList()
fun addBouquet(bouquet: Bouquet) {
favoriteList.add(bouquet)
}
fun addBouquets(vararg bouquets: Bouquet) {
favoriteList.addAll(bouquets)
}
fun removeBouquets(bouquetRemove: Bouquet) : List<Bouquet> {
var list : MutableList<Bouquet> = mutableListOf()
favoriteList.forEach{ bouquet ->
if (bouquet.bouquetId != bouquetRemove.bouquetId) list.add(bouquet)
}
favoriteList = list
return favoriteList
}
fun clearBouquets() {
favoriteList.clear()
}
}
}

View File

@ -0,0 +1,35 @@
package com.example.flowershopapp.Entities.Model
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.PrimaryKey
@Entity(tableName = "orders")
data class Order(
@PrimaryKey(autoGenerate = true)
val orderId: Int?,
@ColumnInfo(name = "date")
val date: String,
@ColumnInfo(name = "sum")
val sum: Int
) {
@Ignore
constructor(
date: String,
sum: Int,
) : this(null, date, sum)
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Order
if (orderId != other.orderId) return false
return true
}
override fun hashCode(): Int {
return orderId ?: -1
}
}

View File

@ -0,0 +1,9 @@
package com.example.flowershopapp.Entities.Model
import androidx.room.Entity
@Entity(primaryKeys = ["orderId", "bouquetId"])
class OrderBouquetCrossRef (
val orderId: Int,
val bouquetId: Int
)

View File

@ -0,0 +1,15 @@
package com.example.flowershopapp.Entities.Model
import androidx.room.Embedded
import androidx.room.Junction
import androidx.room.Relation
data class OrdersWithBouquets(
@Embedded val order: Order,
@Relation(
parentColumn = "orderId",
entityColumn = "bouquetId",
associateBy = Junction(OrderBouquetCrossRef::class)
)
val bouquets: List<Bouquet>
)

View File

@ -0,0 +1,41 @@
package com.example.flowershopapp.Entities.Model
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.PrimaryKey
import org.mindrot.jbcrypt.BCrypt
import java.time.LocalDate
@Entity(tableName = "users")
data class User(
@PrimaryKey(autoGenerate = true)
val userId: Int?,
@ColumnInfo(name = "name")
val userName: String,
@ColumnInfo(name = "dateOfBirth")
val dateOfBirth: String,
@ColumnInfo(name = "phoneNumber")
val phoneNumber: String,
@ColumnInfo(name = "password")
val password: String
) {
@Ignore
constructor(
userName: String,
dateOfBirth: String,
phoneNumber: String,
password: String
) : this(null, userName, dateOfBirth, phoneNumber, password)
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as User
if (userId != other.userId) return false
return true
}
override fun hashCode(): Int {
return userId ?: -1
}
}

View File

@ -0,0 +1,9 @@
package com.example.flowershopapp.Entities.Model
import androidx.room.Entity
@Entity(primaryKeys = ["userId", "orderId"])
class UserOrderCrossRef (
val userId: Int,
val orderId: Int
)

View File

@ -0,0 +1,15 @@
package com.example.flowershopapp.Entities.Model
import androidx.room.Embedded
import androidx.room.Junction
import androidx.room.Relation
data class UsersWithOrders(
@Embedded val user: User,
@Relation(
parentColumn = "userId",
entityColumn = "orderId",
associateBy = Junction(UserOrderCrossRef::class)
)
val orders: List<Order>
)

View File

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M3,13h8L11,3L3,3v10zM3,21h8v-6L3,15v6zM13,21h8L21,11h-8v10zM13,3v6h8L21,3h-8z" />
</vector>

View File

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z" />
</vector>

View File

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z" />
</vector>

View File

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="?attr/actionBarSize">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/bottom_nav_menu" />
<fragment
android:id="@+id/nav_host_fragment_activity_main"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@id/nav_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/mobile_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.dashboard.DashboardFragment">
<TextView
android:id="@+id/text_dashboard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:textAlignment="center"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.home.HomeFragment">
<TextView
android:id="@+id/text_home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:textAlignment="center"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.notifications.NotificationsFragment">
<TextView
android:id="@+id/text_notifications"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:textAlignment="center"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/navigation_home"
android:icon="@drawable/ic_home_black_24dp"
android:title="@string/title_home" />
<item
android:id="@+id/navigation_dashboard"
android:icon="@drawable/ic_dashboard_black_24dp"
android:title="@string/title_dashboard" />
<item
android:id="@+id/navigation_notifications"
android:icon="@drawable/ic_notifications_black_24dp"
android:title="@string/title_notifications" />
</menu>

View File

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mobile_navigation"
app:startDestination="@+id/navigation_home">
<fragment
android:id="@+id/navigation_home"
android:name="com.example.flowershop.ui.home.HomeFragment"
android:label="@string/title_home"
tools:layout="@layout/fragment_home" />
<fragment
android:id="@+id/navigation_dashboard"
android:name="com.example.flowershop.ui.dashboard.DashboardFragment"
android:label="@string/title_dashboard"
tools:layout="@layout/fragment_dashboard" />
<fragment
android:id="@+id/navigation_notifications"
android:name="com.example.flowershop.ui.notifications.NotificationsFragment"
android:label="@string/title_notifications"
tools:layout="@layout/fragment_notifications" />
</navigation>

View File

@ -1,16 +0,0 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.FlowerShop" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_200</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/black</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_200</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>

View File

@ -1,5 +0,0 @@
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>

View File

@ -1,17 +0,0 @@
package com.example.flowershop
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

View File

@ -2,4 +2,5 @@
plugins {
id("com.android.application") version "8.1.2" apply false
id("org.jetbrains.kotlin.android") version "1.8.10" apply false
id("com.google.devtools.ksp") version "1.8.20-1.0.11" apply false
}