lab3
This commit is contained in:
parent
5934717cb6
commit
6fb5b51fb8
1
.idea/.name
Normal file
1
.idea/.name
Normal file
@ -0,0 +1 @@
|
||||
FlowerShopApp
|
17
.idea/deploymentTargetDropDown.xml
Normal file
17
.idea/deploymentTargetDropDown.xml
Normal 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>
|
@ -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>
|
@ -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>
|
3
app/.idea/.gitignore
vendored
3
app/.idea/.gitignore
vendored
@ -1,3 +0,0 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
@ -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>
|
@ -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>
|
@ -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
111
app/.idea/workspace.xml
Normal 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>
|
@ -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")
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
@ -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),
|
||||
)
|
||||
}
|
@ -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)
|
||||
)) {
|
||||
|
@ -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)
|
||||
)) {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
@ -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? {
|
||||
|
@ -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}")
|
||||
}
|
||||
}
|
@ -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("История заказов")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
)) {
|
@ -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()
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
@ -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")
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
)
|
@ -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>
|
||||
)
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
)
|
@ -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>
|
||||
)
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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)
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue
Block a user