Compare commits

...

No commits in common. "main" and "LabWork_03" have entirely different histories.

108 changed files with 4079 additions and 32 deletions

46
.gitignore vendored
View File

@ -1,33 +1,15 @@
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Log/OS Files
*.log
# Android Studio generated files and folders
captures/
.externalNativeBuild/
.cxx/
*.apk
output.json
# IntelliJ
*.iml
.idea/
misc.xml
deploymentTargetDropDown.xml
render.experimental.xml
# Keystore files
*.jks
*.keystore
# Google Services (e.g. APIs or Firebase)
google-services.json
# Android Profiling
*.hprof
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties

3
.idea/.gitignore vendored Normal file
View File

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

1
.idea/.name Normal file
View File

@ -0,0 +1 @@
Android-Programming

6
.idea/compiler.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="19" />
</component>
</project>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<targetSelectedWithDropDown>
<Target>
<type value="QUICK_BOOT_TARGET" />
<deviceKey>
<Key>
<type value="VIRTUAL_DEVICE_PATH" />
<value value="C:\Users\Admin\.android\avd\Pixel_7_Pro_API_30.avd" />
</Key>
</deviceKey>
</Target>
</targetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2023-10-12T15:08:00.916663800Z" />
</component>
</project>

21
.idea/gradle.xml Normal file
View File

@ -0,0 +1,21 @@
<?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="gradleHome" value="$PROJECT_DIR$/../../../../Gradle/gradle-8.3" />
<option name="gradleJvm" value="19" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

View File

@ -0,0 +1,41 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<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>

6
.idea/kotlinc.xml Normal file
View File

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

9
.idea/misc.xml Normal file
View File

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

6
.idea/vcs.xml Normal file
View File

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

1
app/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

86
app/build.gradle.kts Normal file
View File

@ -0,0 +1,86 @@
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id ("kotlin-kapt")
}
android {
namespace = "com.example.android_programming"
compileSdk = 34
defaultConfig {
applicationId = "com.example.android_programming"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_19
targetCompatibility = JavaVersion.VERSION_19
}
kotlinOptions {
jvmTarget = "19"
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.4.3"
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
}
apply(plugin = "kotlin-kapt")
dependencies {
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.03.00"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material:material")
implementation("androidx.navigation:navigation-runtime-ktx:2.7.4")
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.03.00"))
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
implementation ("androidx.activity:activity-ktx:1.8.0")
implementation ("androidx.fragment:fragment-ktx:1.6.1")
implementation ("io.coil-kt:coil-compose:1.4.0")
implementation ("com.google.code.gson:gson:2.8.8")
implementation("androidx.navigation:navigation-compose:2.7.4")
implementation ("androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0-alpha02")
//ROOM
val room_version = "2.5.2"
implementation("androidx.room:room-runtime:$room_version")
annotationProcessor("androidx.room:room-compiler:$room_version")
kapt("androidx.room:room-compiler:$room_version")
implementation("androidx.room:room-ktx:$room_version")
implementation("androidx.room:room-paging:$room_version")
}

21
app/proguard-rules.pro vendored Normal file
View File

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

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

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:name=".App"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AndroidProgramming"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.AndroidProgramming">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@ -0,0 +1,19 @@
package com.example.android_programming
import android.app.Application
import com.example.android_programming.database.AppDatabase
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class App : Application() {
val database by lazy { AppDatabase.getInstance(this)}
override fun onCreate() {
super.onCreate()
// this.deleteDatabase("my-db")
CoroutineScope(Dispatchers.IO).launch {
AppDatabase.populateDatabase()
}
}
}

View File

@ -0,0 +1,54 @@
package com.example.android_programming
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.example.android_programming.composeui.Header.Header
import com.example.android_programming.composeui.Navigation.Navigate
import com.example.android_programming.model.User
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MainContent()
}
}
}
@Composable
fun MainContent() {
Column(
modifier = Modifier.fillMaxSize()
) {
Header()
Navigate()
}
}
class GlobalUser private constructor() {
private var user: User? = null
fun setUser(user: User?) {
this.user = user
}
fun getUser(): User? {
return user
}
companion object {
private var instance: GlobalUser? = null
fun getInstance(): GlobalUser {
return instance ?: synchronized(this) {
instance ?: GlobalUser().also { instance = it }
}
}
}
}

View File

@ -0,0 +1,40 @@
package com.example.android_programming.composeui.Header
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.android_programming.R
@Composable
fun Header() {
Box(
modifier = Modifier
.fillMaxWidth()
.background(Color.White)
) {
Image(
painter = painterResource(id = R.drawable.logo),
contentDescription = "image",
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(0.dp, 10.dp, 0.dp, 0.dp)
)
}
}
@Composable
@Preview
fun NavigatePreview(){
Header()
}

View File

@ -0,0 +1,76 @@
package com.example.android_programming.composeui.Navigation
import androidx.compose.runtime.Composable
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import com.example.android_programming.composeui.Screens.AdminPanel.AddPanel
import com.example.android_programming.composeui.Screens.AdminPanel.AdminPanel
import com.example.android_programming.composeui.Screens.AdminPanel.ChangePanel
import com.example.android_programming.composeui.Screens.AdminPanel.ChangeSneaker
import com.example.android_programming.composeui.Screens.HomeScreen.AboutSneaker
import com.example.android_programming.composeui.Screens.HomeScreen.HomeScreen
import com.example.android_programming.composeui.Screens.MyOrderScreen.MyOrderScreen
import com.example.android_programming.composeui.Screens.OrderScreen.OrderScreen
import com.example.android_programming.composeui.Screens.ProfileScreen.Profile.Person
import com.example.android_programming.composeui.Screens.ProfileScreen.Profile.ProfileScreen
import com.example.android_programming.composeui.Screens.ProfileScreen.SignIn.LoginScreen
import com.example.android_programming.composeui.Screens.ProfileScreen.SignUp.SignUpScreen
import com.example.android_programming.model.Sneaker
import com.example.android_programming.vmodel.OrderViewModel
import com.google.gson.Gson
@Composable
fun NavController(navController: NavHostController){
var orderViewModel: OrderViewModel = viewModel(factory = OrderViewModel.factory)
NavHost(
navController = navController,
startDestination = NavItem.Home.route
){
composable(NavItem.Home.route){
HomeScreen(navController, orderViewModel)
}
composable(NavItem.MyOrder.route){
MyOrderScreen(orderViewModel)
}
composable(NavItem.Order.route){
OrderScreen(orderViewModel, navController)
}
composable(NavItem.Profile.route){
ProfileScreen(navController)
}
composable(NavItem.SignIn.route){
LoginScreen(navController)
}
composable(NavItem.SignUp.route){
SignUpScreen(navController)
}
composable(NavItem.Person.route){
Person(navController)
}
composable(NavItem.AdminPanel.route){
AdminPanel(navController)
}
composable(NavItem.AddPanel.route){
AddPanel()
}
composable(NavItem.ChangePanel.route){
ChangePanel(navController)
}
composable(NavItem.AboutSneaker.route) { backStackEntry ->
val sneakerItemString = backStackEntry.arguments?.getString("sneakerItem")
val sneakerItem = Gson().fromJson(sneakerItemString, Sneaker::class.java)
sneakerItem?.let { AboutSneaker(it, onBackClick = {
navController.navigateUp() })
}
}
composable(NavItem.ChangeSneaker.route) { backStackEntry ->
val sneakerItemString = backStackEntry.arguments?.getString("sneakerItem")
val sneakerItem = Gson().fromJson(sneakerItemString, Sneaker::class.java)
sneakerItem?.let { ChangeSneaker(it, onBackClick = {
navController.navigateUp() })
}
}
}
}

View File

@ -0,0 +1,23 @@
package com.example.android_programming.composeui.Navigation
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Build
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Person
import androidx.compose.material.icons.filled.ShoppingCart
import androidx.compose.ui.graphics.vector.ImageVector
sealed class NavItem(val route: String, val icon: ImageVector?){
object Home : NavItem("home", Icons.Default.Home)
object MyOrder : NavItem("myorder", null)
object Order : NavItem("order", Icons.Default.ShoppingCart)
object Profile : NavItem("profile", Icons.Default.Person)
object SignIn : NavItem("login", null)
object SignUp : NavItem("signup", null)
object Person : NavItem("person", null)
object AdminPanel : NavItem("admin", Icons.Default.Build)
object AddPanel : NavItem("add", null)
object ChangePanel : NavItem("change", null)
object AboutSneaker : NavItem("aboutSneaker/{sneakerItem}", null)
object ChangeSneaker : NavItem("changeSneaker/{sneakerItem}", null)
}

View File

@ -0,0 +1,81 @@
package com.example.android_programming.composeui.Navigation
import android.annotation.SuppressLint
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.BottomNavigation
import androidx.compose.material.BottomNavigationItem
import androidx.compose.material.Icon
import androidx.compose.material.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.unit.dp
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.example.android_programming.R
@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
@Composable
fun Navigate() {
val navController = rememberNavController()
val Items = listOf(
NavItem.Home,
NavItem.Order,
NavItem.Profile,
NavItem.AdminPanel,
)
Scaffold(bottomBar = {
// Оставьте код навигационного бара без изменений
BottomNavigation(
backgroundColor = Color.White
) {
val navBackStackEntry = navController.currentBackStackEntryAsState()
val currentState = navBackStackEntry.value
Items.forEach { it ->
val isSelected = currentState?.destination?.route == it.route
BottomNavigationItem(
selected = isSelected,
onClick = {
if (!isSelected) {
navController.graph.startDestinationRoute?.let {
navController.popBackStack(it, inclusive = true)
}
navController.navigate(it.route) {
launchSingleTop
}
}
navController.navigate(it.route)
},
icon = {
val iconModifier = if (isSelected) {
Modifier
.background(color = colorResource(id = R.color.figma_blue), shape = CircleShape)
.padding(8.dp)
} else {
Modifier
}
it.icon?.let { it1 ->
Icon(
imageVector = it1,
contentDescription = null,
tint = if (isSelected) Color.White else Color.Unspecified,
modifier = iconModifier.then(Modifier.size(24.dp))
)
}
}
)
}
}
}) {
NavController(navController = navController)
}
}

View File

@ -0,0 +1,205 @@
package com.example.android_programming.composeui.Screens.AdminPanel
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.android_programming.R
import com.example.android_programming.model.PhotoManager
import com.example.android_programming.vmodel.SneakerViewModel
@Composable
fun AddPanel(sneakerViewModel: SneakerViewModel = viewModel(factory = SneakerViewModel.factory)){
val photoManager = PhotoManager()
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.clip(RoundedCornerShape(16.dp))
.background(colorResource(id = R.color.figma))
.verticalScroll(rememberScrollState())
) {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Image(
painter = painterResource(id = sneakerViewModel.photo.value),
contentDescription = "image",
contentScale = ContentScale.FillHeight,
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.height(200.dp)
)
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
sneakerViewModel.photo.value = photoManager.changePhoto(sneakerViewModel.photo.value)
},
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 0.dp, 16.dp, 16.dp)
) {
Text("Add image")
}
TextField(
value = sneakerViewModel.brand.value,
onValueChange = { sneakerViewModel.brand.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Brand",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = sneakerViewModel.model.value,
onValueChange = { sneakerViewModel.model.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Model",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = sneakerViewModel.description.value,
onValueChange = { sneakerViewModel.description.value = it },
modifier = Modifier
.fillMaxWidth()
.height(150.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Description",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = sneakerViewModel.price.value,
onValueChange = { sneakerViewModel.price.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Price",
style = TextStyle(fontSize = 12.sp)
)
}
)
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
sneakerViewModel.insertSneaker()
},
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Text("Add sneaker")
}
}
}
}

View File

@ -0,0 +1,72 @@
package com.example.android_programming.composeui.Screens.AdminPanel
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.AlertDialog
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import com.example.android_programming.GlobalUser
import com.example.android_programming.model.RoleEnum
@Composable
fun AdminPanel(navHostController: NavHostController) {
var isAddPanelVisible by remember { mutableStateOf(false) }
var isChangePanelVisible by remember { mutableStateOf(false) }
var showDialog by remember { mutableStateOf(GlobalUser.getInstance().getUser()?.role == RoleEnum.User || GlobalUser.getInstance().getUser()?.role == null) }
if (!showDialog) {
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
.padding(bottom = 50.dp)
) {
ButtonAdmin(
onAddClick = {
isAddPanelVisible = true
isChangePanelVisible = false
},
onChangeClick = {
isChangePanelVisible = true
isAddPanelVisible = false
}
)
}
if (isAddPanelVisible) {
AddPanel()
}
if (isChangePanelVisible) {
ChangePanel(navHostController)
}
}
if (showDialog) {
AlertDialog(
onDismissRequest = { showDialog = false },
title = {
Text("Access denied")
},
text = {
Text("You are not admin")
},
confirmButton = {
Button(
onClick = { navHostController.navigate("home") }
) {
Text("OK")
}
}
)
}
}

View File

@ -0,0 +1,60 @@
package com.example.android_programming.composeui.Screens.AdminPanel
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.unit.dp
import com.example.android_programming.R
@Composable
fun ButtonAdmin(onAddClick: () -> Unit, onChangeClick: () -> Unit) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 16.dp, 16.dp, 0.dp)
.clip(RoundedCornerShape(16.dp))
.background(colorResource(id = R.color.figma))
){
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
onAddClick()
},
modifier = Modifier
.clip(RoundedCornerShape(20.dp))
.fillMaxWidth(0.5f)
.padding(16.dp)
) {
Text("Add")
}
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
onChangeClick()
},
modifier = Modifier
.clip(RoundedCornerShape(20.dp))
.fillMaxWidth()
.padding(16.dp)
) {
Text("Change/Del")
}
}
}

View File

@ -0,0 +1,98 @@
package com.example.android_programming.composeui.Screens.AdminPanel
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Create
import androidx.compose.material.icons.filled.Delete
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import com.example.android_programming.R
import com.example.android_programming.model.Sneaker
import com.example.android_programming.vmodel.SneakerViewModel
import com.google.gson.Gson
@Composable
fun CardSneakerForChange(item: Sneaker, navController: NavHostController, sneakerViewModel: SneakerViewModel = viewModel(factory = SneakerViewModel.factory)) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(0.dp, 0.dp, 0.dp, 16.dp)
.clip(RoundedCornerShape(10.dp))
.background(colorResource(id = R.color.figma)),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Image(
painter = painterResource(id = item.photo),
contentDescription = "image",
contentScale = ContentScale.FillWidth,
modifier = Modifier
.size(70.dp)
.padding(10.dp)
.clip(RoundedCornerShape(10.dp))
)
Column(
modifier = Modifier
.weight(1f)
.padding(start = 16.dp)
) {
item.brand?.let { Text(text = it, fontSize = 20.sp) }
Text(text = "${item.price} $", color = Color.Red, fontSize = 16.sp)
}
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
sneakerViewModel.brand.value = item.brand ?: ""
sneakerViewModel.model.value = item.model ?: ""
sneakerViewModel.description.value = item.description ?: ""
sneakerViewModel.price.value = item.price.toString()
val sneakerItemString = Gson().toJson(item)
navController.navigate("changeSneaker/${sneakerItemString}") },
modifier = Modifier
.padding(end = 16.dp)
) {
Icon(imageVector = Icons.Default.Create, contentDescription = "change")
}
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
sneakerViewModel.deleteSneaker(item)
},
modifier = Modifier
.padding(end = 16.dp)
) {
Icon(imageVector = Icons.Default.Delete, contentDescription = "delete")
}
}
}

View File

@ -0,0 +1,40 @@
package com.example.android_programming.composeui.Screens.AdminPanel
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import com.example.android_programming.vmodel.SneakerViewModel
@Composable
fun ChangePanel(navHostController: NavHostController, sneakerViewModel: SneakerViewModel = viewModel(factory = SneakerViewModel.factory)) {
val list = sneakerViewModel.SneakerList.collectAsState(initial = emptyList()).value
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
.padding(16.dp)
){
Row {
LazyColumn(
modifier = Modifier
.fillMaxSize()
) {
itemsIndexed(list
){_, item->
CardSneakerForChange(item = item, navHostController)
}
}
}
}
}

View File

@ -0,0 +1,241 @@
package com.example.android_programming.composeui.Screens.AdminPanel
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.android_programming.R
import com.example.android_programming.model.PhotoManager
import com.example.android_programming.model.Sneaker
import com.example.android_programming.vmodel.SneakerViewModel
@Composable
fun ChangeSneaker(sneaker: Sneaker, onBackClick: () -> Unit, sneakerViewModel: SneakerViewModel = viewModel(factory = SneakerViewModel.factory)) {
val brand = remember {mutableStateOf(sneaker.brand)}
val model = remember{mutableStateOf(sneaker.model)}
val description = remember{mutableStateOf(sneaker.description)}
val price = remember{mutableStateOf(sneaker.price.toString())}
var photo by remember { mutableStateOf(sneaker.photo) }
val photoManager = PhotoManager()
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 16.dp, 16.dp, 50.dp)
.clip(RoundedCornerShape(16.dp))
.background(colorResource(id = R.color.figma))
.verticalScroll(rememberScrollState())
) {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Button(
onClick = onBackClick,
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.white),
contentColor = Color.Black
),
) {
Icon(
imageVector = Icons.Default.ArrowBack,
contentDescription = "Back",
)
}
Image(
painter = painterResource(id = photo),
contentDescription = "image",
contentScale = ContentScale.FillHeight,
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.height(200.dp)
)
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
photo = photoManager.changePhoto(photo)
},
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 0.dp, 16.dp, 16.dp)
) {
Text("Change image")
}
TextField(
value = brand.value,
onValueChange = { newValue -> brand.value = newValue },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Brand",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = model.value,
onValueChange = { model.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Model",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = description.value,
onValueChange = { description.value = it },
modifier = Modifier
.fillMaxWidth()
.height(150.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Description",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = price.value,
onValueChange = { price.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Price",
style = TextStyle(fontSize = 12.sp)
)
}
)
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
sneakerViewModel.UpdateSneaker(
Sneaker(
sneakerId = sneaker.sneakerId,
brand = brand.value,
model = model.value,
description = description.value,
photo = photo,
price = price.value.toDouble()
)
)
onBackClick()
},
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Text("Save")
}
}
}
}

View File

@ -0,0 +1,90 @@
package com.example.android_programming.composeui.Screens.HomeScreen
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
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.shape.RoundedCornerShape
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.android_programming.R
import com.example.android_programming.model.Sneaker
@Composable
fun AboutSneaker(sneaker: Sneaker, onBackClick: () -> Unit) {
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
.padding(20.dp)
) {
Button(
onClick = onBackClick,
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.white),
contentColor = Color.Black
),
) {
Icon(
imageVector = Icons.Default.ArrowBack,
contentDescription = "Back",
)
}
Image(
painter = painterResource(id = sneaker.photo),
contentDescription = "image",
contentScale = ContentScale.FillWidth,
modifier = Modifier
.fillMaxWidth()
.height(300.dp)
)
Column(
modifier = Modifier.padding(16.dp)
) {
Text(
text = "${sneaker.brand}",
fontSize = 25.sp,
fontWeight = FontWeight.Bold
)
Text(
text = "${sneaker.model}",
fontSize = 25.sp,
fontWeight = FontWeight.Bold
)
Text(text = "Price: $${sneaker.price}", fontSize = 16.sp)
Text(text = "Description: ${sneaker.description}", fontSize = 16.sp)
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
},
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(20.dp))
) {
Text("Add to cart")
}
}
}
}

View File

@ -0,0 +1,38 @@
package com.example.android_programming.composeui.Screens.HomeScreen.FilterByBrand
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.LazyRow
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.android_programming.R
@Preview
@Composable
fun FilterByBrand() {
Row {
LazyRow(
modifier = Modifier
.fillMaxWidth()
.padding(0.dp, 10.dp, 0.dp, 5.dp),
horizontalArrangement = Arrangement.SpaceEvenly
){
itemsIndexed(
listOf(
ItemFilterByBrand(R.drawable.jordan),
ItemFilterByBrand(R.drawable.jordan),
ItemFilterByBrand(R.drawable.jordan),
ItemFilterByBrand(R.drawable.jordan)
)
){ _, item->
ItemRow(item = item)
}
}
}
}

View File

@ -0,0 +1,5 @@
package com.example.android_programming.composeui.Screens.HomeScreen.FilterByBrand
data class ItemFilterByBrand(
val imageId: Int,
)

View File

@ -0,0 +1,45 @@
package com.example.android_programming.composeui.Screens.HomeScreen.FilterByBrand
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.android_programming.R
@Composable
fun ItemRow(item: ItemFilterByBrand) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.clip(RoundedCornerShape(10.dp))
.background(colorResource(id = R.color.figma))
) {
Image(
painter = painterResource(id = item.imageId),
contentDescription = "image",
contentScale = ContentScale.Crop,
modifier = Modifier
.padding(13.dp, 3.dp, 13.dp, 3.dp)
.size(30.dp)
)
}
}
@Composable
@Preview
fun PreviewItemRow(){
ItemRow(item = ItemFilterByBrand(R.drawable.jordan))
}

View File

@ -0,0 +1,52 @@
package com.example.android_programming.composeui.Screens.HomeScreen
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import com.example.android_programming.composeui.Screens.HomeScreen.FilterByBrand.FilterByBrand
import com.example.android_programming.composeui.Screens.HomeScreen.SearchField.SearchField
import com.example.android_programming.composeui.Screens.HomeScreen.SneakerRecyclerView.RecyclerView
import com.example.android_programming.model.Sneaker
import com.example.android_programming.vmodel.OrderViewModel
@Composable
fun HomeScreen(navHostController: NavHostController, orderViewModel: OrderViewModel) {
val context = LocalContext.current
val sneakers = remember { mutableStateListOf<Sneaker>() }
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
.verticalScroll(rememberScrollState())
) {
Row {
// Поле для поиска
SearchField(
modifier = Modifier
.fillMaxWidth()
.padding(20.dp, 20.dp, 20.dp, 10.dp)
.clip(RoundedCornerShape(10.dp))
) { searchText ->
// Обработка введенного текста поиска
}
}
Sales()
FilterByBrand()
RecyclerView(navHostController = navHostController, orderViewModel)
}
}

View File

@ -0,0 +1,30 @@
package com.example.android_programming.composeui.Screens.HomeScreen
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.android_programming.R
@Composable
@Preview
fun Sales() {
Row(
modifier = Modifier
.padding(16.dp, 0.dp)
){
Image(
painter = painterResource(id = R.drawable.sales),
contentDescription = "image",
contentScale = ContentScale.FillWidth,
modifier = Modifier
.fillMaxWidth()
)
}
}

View File

@ -0,0 +1,79 @@
package com.example.android_programming.composeui.Screens.HomeScreen.SearchField;
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material.Icon
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Search
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
import com.example.android_programming.R
@Composable
fun SearchField(
modifier: Modifier = Modifier,
onSearch: (String) -> Unit
) {
var searchText by remember { mutableStateOf("") }
Box(
modifier = modifier
.fillMaxWidth()
.background(colorResource(id = R.color.figma))
.padding(horizontal = 16.dp, vertical = 8.dp)
) {
Row(
modifier = Modifier
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
content = {
BasicTextField(
value = searchText,
onValueChange = {
searchText = it
onSearch(it)
},
textStyle = TextStyle(color = Color.Black),
modifier = Modifier
.weight(1f)
)
SearchIcon(
imageVector = Icons.Default.Search,
contentDescription = "Search Icon",
modifier = Modifier.size(24.dp)
)
}
)
}
}
@Composable
fun SearchIcon(
imageVector: ImageVector,
contentDescription: String,
modifier: Modifier = Modifier
) {
Icon(
imageVector = imageVector,
contentDescription = contentDescription,
modifier = modifier
.size(24.dp)
.padding(4.dp)
)
}

View File

@ -0,0 +1,106 @@
package com.example.android_programming.composeui.Screens.HomeScreen.SneakerRecyclerView
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ShoppingCart
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import com.example.android_programming.R
import com.example.android_programming.model.Sneaker
import com.google.gson.Gson
@Composable
fun CardSneaker(item: Sneaker, navController: NavHostController, selectedItems: List<Sneaker>, onItemSelected: (Sneaker) -> Unit) {
val maxWidth = (LocalConfiguration.current.screenWidthDp / 2).dp
Box(
modifier = Modifier
.padding(4.dp)
.widthIn(maxWidth)
.clickable {
val sneakerItemString = Gson().toJson(item)
navController.navigate("aboutSneaker/${sneakerItemString}")
}
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.clip(RoundedCornerShape(10.dp))
.background(colorResource(id = R.color.figma))
.widthIn(maxWidth)
) {
Image(
painter = painterResource(id = item.photo),
contentDescription = "image",
contentScale = ContentScale.FillWidth,
modifier = Modifier
.size(100.dp)
)
Column {
Row(
modifier = Modifier
.widthIn(maxWidth),
horizontalArrangement = Arrangement.SpaceBetween,
) {
Column(
horizontalAlignment = Alignment.Start,
modifier = Modifier
.padding(10.dp, 0.dp)
) {
Row {
item.brand?.let { Text(text = "$it ") }
item.model?.let { Text(text = it) }
}
Text(text = item.price.toString(), color = Color.Red)
}
Column(
modifier = Modifier
.padding(10.dp)
) {
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
onItemSelected(item)
},
modifier = Modifier
.size(50.dp, 30.dp)
.clip(RoundedCornerShape(10.dp))
) {
Icon(
imageVector = Icons.Default.ShoppingCart,
contentDescription = null
)
}
}
}
}
}
}
}

View File

@ -0,0 +1,43 @@
package com.example.android_programming.composeui.Screens.HomeScreen.SneakerRecyclerView
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import com.example.android_programming.vmodel.OrderViewModel
import com.example.android_programming.vmodel.SneakerViewModel
@Composable
fun RecyclerView(navHostController : NavHostController, orderViewModel: OrderViewModel, sneakerViewModel: SneakerViewModel = viewModel(factory = SneakerViewModel.factory)) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(bottom = 60.dp)
) {
val list = sneakerViewModel.SneakerList.collectAsState(initial = emptyList()).value
val numColumns = 2
val chunkedList = list.chunked(numColumns)
for (chunkedListItem in chunkedList) {
Row(
horizontalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxWidth()
) {
for (item in chunkedListItem) {
CardSneaker(item, navHostController, orderViewModel.selectedItems) { selectedItem ->
orderViewModel.addSelectedItem(selectedItem)
}
}
}
}
}
}

View File

@ -0,0 +1,57 @@
package com.example.android_programming.composeui.Screens.MyOrderScreen
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.example.android_programming.GlobalUser
import com.example.android_programming.model.Order
import com.example.android_programming.vmodel.OrderViewModel
@Composable
fun MyOrderScreen(orderViewModel: OrderViewModel) {
val userWithOrder by orderViewModel.database.userDao().getUserOrders(GlobalUser.getInstance().getUser()?.userId!!).collectAsState(null)
val orderList: List<Order>? = userWithOrder?.orders
println()
Column(
modifier = Modifier
.padding(bottom = 50.dp)
.fillMaxSize()
.background(Color.White)
.verticalScroll(rememberScrollState())
){
Text(
text = "My order",
style = MaterialTheme.typography.h5,
fontWeight = FontWeight.Bold,
modifier = Modifier
.padding(10.dp, 10.dp)
)
Row {
Column(
modifier = Modifier
.fillMaxSize()
) {
if (orderList != null) {
for (item in orderList) {
OrderCard(item, orderViewModel)
}
}
}
}
}
}

View File

@ -0,0 +1,87 @@
package com.example.android_programming.composeui.Screens.MyOrderScreen
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import com.example.android_programming.R
import com.example.android_programming.model.Order
import com.example.android_programming.model.Sneaker
import com.example.android_programming.vmodel.OrderViewModel
import java.util.Date
@Composable
fun OrderCard(order: Order, orderViewModel: OrderViewModel){
val SneakerList = order.orderId?.let {
orderViewModel.database.orderDao().getOrderWithSneakers(
it
)
}
val sneakerWithOrder by SneakerList!!.collectAsState(null)
val sneakerList: List<Sneaker>? = sneakerWithOrder?.sneakers
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 16.dp, 16.dp, 0.dp)
.clip(RoundedCornerShape(16.dp))
.background(colorResource(id = R.color.figma))
){
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
verticalArrangement = Arrangement.Center
){
Text("${order.orderId}")
Text("${Date(order.date)}")
Row(){
if (sneakerList != null) {
for(sneaker in sneakerList){
Image(
contentScale = ContentScale.FillBounds,
painter = painterResource(id = sneaker.photo),
contentDescription = null,
modifier = Modifier
.size(70.dp)
.padding(0.dp, 10.dp, 10.dp, 10.dp)
)
}
}
}
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
orderViewModel.deleteOrder(order)
},
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 16.dp, 16.dp, 0.dp)
) {
Text("Cancel")
}
}
}
}

View File

@ -0,0 +1,76 @@
package com.example.android_programming.composeui.Screens.OrderScreen
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.android_programming.R
import com.example.android_programming.model.Sneaker
import com.example.android_programming.vmodel.OrderViewModel
@Composable
fun CardSneakerLike(item: Sneaker, orderViewModel: OrderViewModel) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 5.dp)
.clip(RoundedCornerShape(10.dp))
.background(colorResource(id = R.color.figma)),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Image(
painter = painterResource(id = item.photo),
contentDescription = "image",
contentScale = ContentScale.FillWidth,
modifier = Modifier
.size(70.dp)
.padding(10.dp)
.clip(RoundedCornerShape(10.dp))
)
Column(
modifier = Modifier
.weight(1f)
.padding(start = 16.dp)
) {
item.brand?.let { Text(text = it, fontSize = 20.sp) }
Text(text = "${item.price} USD", color = Color.Red, fontSize = 16.sp)
}
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
orderViewModel.removeSelectedItem(item)
},
modifier = Modifier
.padding(end = 16.dp)
) {
Icon(imageVector = Icons.Default.Delete, contentDescription = "delete")
}
}
}

View File

@ -0,0 +1,132 @@
package com.example.android_programming.composeui.Screens.OrderScreen
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.android_programming.R
import com.example.android_programming.vmodel.OrderViewModel
@Composable
fun DeliveryAddress(orderViewModel: OrderViewModel) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.clip(RoundedCornerShape(16.dp))
.background(colorResource(id = R.color.figma)),
horizontalArrangement = Arrangement.Center
) {
Column(
modifier = Modifier
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "Delivery Address", fontSize = 24.sp, fontWeight = FontWeight.Bold)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = orderViewModel.city.value,
onValueChange = { orderViewModel.city.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "City",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = orderViewModel.street.value,
onValueChange = { orderViewModel.street.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Street",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = orderViewModel.house.value,
onValueChange = { orderViewModel.house.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "House",
style = TextStyle(fontSize = 12.sp)
)
}
)
}
}
}

View File

@ -0,0 +1,57 @@
package com.example.android_programming.composeui.Screens.OrderScreen
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import com.example.android_programming.GlobalUser
import com.example.android_programming.R
import com.example.android_programming.vmodel.OrderViewModel
@Composable
fun OrderScreen(orderViewModel: OrderViewModel, navHostController: NavHostController) {
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
.padding(bottom = 60.dp)
.verticalScroll(rememberScrollState())
){
DeliveryAddress(orderViewModel)
ShoppingList(orderViewModel.selectedItems, orderViewModel)
SubTotal(orderViewModel)
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
if(GlobalUser.getInstance().getUser() != null){
orderViewModel.createOrder()
navHostController.navigate("home")
}else{
navHostController.navigate("login")
}
},
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 0.dp, 16.dp, 16.dp)
) {
Text("Confirm order")
}
}
}

View File

@ -0,0 +1,18 @@
package com.example.android_programming.composeui.Screens.OrderScreen
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.Composable
import com.example.android_programming.model.Sneaker
import com.example.android_programming.vmodel.OrderViewModel
@Composable
fun ShoppingList(list : List<Sneaker>, orderViewModel: OrderViewModel) {
Row {
Column {
for(item in list){
CardSneakerLike(item = item, orderViewModel)
}
}
}
}

View File

@ -0,0 +1,86 @@
package com.example.android_programming.composeui.Screens.OrderScreen
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.android_programming.R
import com.example.android_programming.vmodel.OrderViewModel
@Composable
fun SubTotal(orderViewModel: OrderViewModel) {
Column(
modifier = Modifier
.padding(16.dp)
.clip(RoundedCornerShape(16.dp))
.background(colorResource(id = R.color.figma))
){
Row(
modifier = Modifier
.padding(10.dp, 5.dp)
.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
){
Row(
modifier = Modifier.weight(1f),
horizontalArrangement = Arrangement.Start
){
Text(text = "Sub total", fontSize = 15.sp)
}
Row(
modifier = Modifier.weight(1f),
horizontalArrangement = Arrangement.End
){
Text(text = "${orderViewModel.getSubTotal()} $", fontSize = 15.sp)
}
}
Row(
modifier = Modifier
.padding(10.dp, 5.dp)
.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
){
Row(
modifier = Modifier.weight(1f),
horizontalArrangement = Arrangement.Start
){
Text(text = "Taxes", fontSize = 15.sp)
}
Row(
modifier = Modifier.weight(1f),
horizontalArrangement = Arrangement.End
){
Text(text = "${"%.2f".format(orderViewModel.getSubTotal() * 0.05)} $", fontSize = 15.sp)
}
}
Row(
modifier = Modifier
.padding(10.dp, 5.dp)
.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
){
Row(
modifier = Modifier.weight(1f),
horizontalArrangement = Arrangement.Start
){
Text(text = "Total", fontSize = 15.sp)
}
Row(
modifier = Modifier.weight(1f),
horizontalArrangement = Arrangement.End
){
Text(text = "${"%.2f".format(orderViewModel.getSubTotal() + orderViewModel.getSubTotal() * 0.05)} $", fontSize = 15.sp)
}
}
}
}

View File

@ -0,0 +1,44 @@
package com.example.android_programming.composeui.Screens.ProfileScreen.Profile
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import com.example.android_programming.GlobalUser
import com.example.android_programming.R
@Composable
fun Person(navHostController: NavHostController) {
Column(
modifier = Modifier
.background(Color.White)
.fillMaxSize(),
verticalArrangement = Arrangement.Center
) {
Button(
onClick = {
GlobalUser.getInstance().setUser(null)
navHostController.navigate("profile")
},
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.white),
contentColor = Color.Black
),
modifier = Modifier
.padding(16.dp, 0.dp)
) {
Text("Exit")
}
ProfileCard(navHostController)
}
}

View File

@ -0,0 +1,86 @@
package com.example.android_programming.composeui.Screens.ProfileScreen.Profile
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavHostController
import com.example.android_programming.GlobalUser
import com.example.android_programming.R
@Composable
fun ProfileCard(navHostController: NavHostController) {
val globalUser = GlobalUser.getInstance().getUser()
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.clip(RoundedCornerShape(16.dp))
.background(colorResource(id = R.color.figma))
){
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
){
Image(
contentScale = ContentScale.Crop,
painter = painterResource(id = R.drawable.shailushai),
contentDescription = null,
modifier = Modifier
.size(150.dp)
.border(2.dp, Color.White, CircleShape)
.padding(16.dp)
.clip(CircleShape)
)
if (globalUser != null) {
Text(
text = "${globalUser.name} ${globalUser.surname}",
fontSize = 18.sp,
fontWeight = FontWeight.Bold
)
Text(
text = globalUser.email,
fontSize = 16.sp,
color = Color.Gray
)
}
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
navHostController.navigate("myorder")
},
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 16.dp, 16.dp, 0.dp)
) {
Text("My order")
}
}
}
}

View File

@ -0,0 +1,25 @@
package com.example.android_programming.composeui.Screens.ProfileScreen.Profile;
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.example.android_programming.GlobalUser
import com.example.android_programming.composeui.Screens.ProfileScreen.SignIn.LoginScreen
@Composable
fun ProfileScreen(navController: NavHostController) {
val globalUser: GlobalUser = GlobalUser.getInstance()
if(globalUser.getUser() != null){
Person(navController)
}else{
LoginScreen(navController = navController)
}
}
@Composable
@Preview
fun ProfileScreenPreview(){
val navController = rememberNavController()
ProfileScreen(navController = navController)
}

View File

@ -0,0 +1,170 @@
package com.example.android_programming.composeui.Screens.ProfileScreen.SignIn
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.ClickableText
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
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.NavHostController
import com.example.android_programming.R
import com.example.android_programming.vmodel.UserViewModel
@Composable
fun SignInCard(navController: NavHostController, userViewModel: UserViewModel = viewModel(factory = UserViewModel.factory)) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.clip(RoundedCornerShape(16.dp))
.background(colorResource(id = R.color.figma))
){
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
){
var isEmailValid by remember { mutableStateOf(true) }
var isPasswordValid by remember { mutableStateOf(true) }
Text(
text = "Sign In",
fontSize = 24.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier
.padding(16.dp)
)
TextField(
value = userViewModel.email.value,
onValueChange = {
userViewModel.email.value = it
isEmailValid = userViewModel.isValidEmail(it)},
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Email",
style = TextStyle(fontSize = 12.sp)
)
}
)
if (!isEmailValid) {
Text(
text = "Invalid email format",
color = Color.Red,
style = TextStyle(fontSize = 12.sp)
)
}
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = userViewModel.password.value,
onValueChange = {
userViewModel.password.value = it
isPasswordValid = it.isNotEmpty()
},
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
visualTransformation = PasswordVisualTransformation(),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Password",
style = TextStyle(fontSize = 12.sp)
)
}
)
if (!isPasswordValid) {
Text(
text = "Password is required",
color = Color.Red,
style = TextStyle(fontSize = 12.sp)
)
}
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
userViewModel.authUser()
navController.navigate("profile")
},
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 16.dp, 16.dp, 0.dp)
) {
Text("Sign In")
}
ClickableText(
text = AnnotatedString("You do not have an account? Register!"),
modifier = Modifier
.padding(0.dp, 0.dp, 0.dp, 16.dp),
onClick = {
navController.navigate("signup")
}
)
}
}
}

View File

@ -0,0 +1,21 @@
package com.example.android_programming.composeui.Screens.ProfileScreen.SignIn
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.navigation.NavHostController
@Composable
fun LoginScreen(navController: NavHostController) {
Column(modifier = Modifier
.fillMaxSize()
.background(Color.White),
verticalArrangement = Arrangement.Center
) {
SignInCard(navController)
}
}

View File

@ -0,0 +1,190 @@
package com.example.android_programming.composeui.Screens.ProfileScreen.SignUp
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
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.NavHostController
import com.example.android_programming.R
import com.example.android_programming.vmodel.UserViewModel
@Composable
fun SignUpCard(navHostController: NavHostController, userViewModel: UserViewModel = viewModel(factory = UserViewModel.factory)) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.clip(RoundedCornerShape(16.dp))
.background(colorResource(id = R.color.figma))
){
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
){
Text(
text = "Sign Up",
fontSize = 24.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier
.padding(16.dp)
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = userViewModel.name.value,
onValueChange = { userViewModel.name.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Name",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = userViewModel.surname.value,
onValueChange = { userViewModel.surname.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Surname",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = userViewModel.email.value,
onValueChange = { userViewModel.email.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Email",
style = TextStyle(fontSize = 12.sp)
)
}
)
Spacer(modifier = Modifier.height(16.dp))
TextField(
value = userViewModel.password.value,
onValueChange = { userViewModel.password.value = it },
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(16.dp, 0.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(4.dp)),
singleLine = true,
visualTransformation = PasswordVisualTransformation(),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(
onNext = {
}
),
placeholder = {
Text(
text = "Password",
style = TextStyle(fontSize = 12.sp)
)
}
)
Button(
colors = ButtonDefaults.buttonColors(
backgroundColor = colorResource(id = R.color.figma_blue),
contentColor = Color.White
),
onClick = {
userViewModel.createUser()
navHostController.navigate("login")
},
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Text("Sign Up")
}
}
}
}

View File

@ -0,0 +1,21 @@
package com.example.android_programming.composeui.Screens.ProfileScreen.SignUp
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.navigation.NavHostController
@Composable
fun SignUpScreen(navHostController: NavHostController) {
Column(modifier = Modifier
.fillMaxSize()
.background(Color.White),
verticalArrangement = Arrangement.Center
) {
SignUpCard(navHostController)
}
}

View File

@ -0,0 +1,29 @@
package com.example.android_programming.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import com.example.android_programming.model.Order
import com.example.android_programming.model.OrderSneaker
import com.example.android_programming.model.OrderWithSneakers
import kotlinx.coroutines.flow.Flow
@Dao
interface OrderDao {
@Insert
suspend fun createOrder(order: Order): Long
@Insert
suspend fun insertOrderSneaker(orderSneaker: OrderSneaker)
@Query("SELECT * FROM 'Order' WHERE orderId = :id")
fun getOrderWithSneakers(id: Int): Flow<OrderWithSneakers>
@Query("SELECT * FROM `Order`")
fun getAllOrder(): Flow<List<Order>>
@Delete
suspend fun delete(order: Order)
}

View File

@ -0,0 +1,27 @@
package com.example.android_programming.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.android_programming.model.Sneaker
import kotlinx.coroutines.flow.Flow
@Dao
interface SneakerDao {
@Insert
suspend fun insert(sneaker: Sneaker)
@Update
suspend fun update(sneaker: Sneaker)
@Delete
suspend fun delete(sneaker: Sneaker)
@Query("SELECT*FROM Sneaker")
fun getAllSneakers(): Flow<List<Sneaker>>
@Query("SELECT * FROM Sneaker WHERE sneakerId = :id")
suspend fun getSneakerById(id: Int): Sneaker
}

View File

@ -0,0 +1,31 @@
package com.example.android_programming.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.android_programming.model.User
import com.example.android_programming.model.UserWithOrder
import kotlinx.coroutines.flow.Flow
@Dao
interface UserDao {
@Insert
suspend fun createUser(user: User)
@Update
suspend fun updateUser(user: User)
@Delete
suspend fun deleteUser(user: User)
@Query("SELECT * FROM users WHERE userId = :id")
suspend fun getUserById(id: Int): User
@Query("SELECT * FROM users WHERE email = :email")
suspend fun getUserByEmail(email: String): User
@Query("SELECT * FROM users WHERE userId =:id")
fun getUserOrders(id: Int) : Flow<UserWithOrder>
}

View File

@ -0,0 +1,78 @@
package com.example.android_programming.database
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.sqlite.db.SupportSQLiteDatabase
import com.example.android_programming.R
import com.example.android_programming.dao.OrderDao
import com.example.android_programming.dao.SneakerDao
import com.example.android_programming.dao.UserDao
import com.example.android_programming.model.Order
import com.example.android_programming.model.OrderSneaker
import com.example.android_programming.model.RoleEnum
import com.example.android_programming.model.Sneaker
import com.example.android_programming.model.User
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@Database(entities = [Sneaker::class, User::class, Order::class, OrderSneaker::class], version = 5)
abstract class AppDatabase : RoomDatabase() {
abstract fun sneakerDao(): SneakerDao
abstract fun userDao(): UserDao
abstract fun orderDao(): OrderDao
companion object {
private const val DB_NAME: String = "my-db"
@Volatile
private var INSTANCE: AppDatabase? = null
suspend fun populateDatabase() {
INSTANCE?.let { database ->
// User
val userDao = database.userDao()
val user1 = User(null, "Artem", "Emelyanov", "artem@mail.ru", "123", RoleEnum.Admin)
val user2 = User(null, "Danil", "Markov", "danil@mail.ru", "123", RoleEnum.User)
val user3 = User(null, "Viktoria", "Presnyakova", "vika@mail.ru", "123", RoleEnum.User)
userDao.createUser(user1)
userDao.createUser(user2)
userDao.createUser(user3)
// Sneaker
val sneakerDao = database.sneakerDao()
val sneaker1 = Sneaker(null, "Nike", "Air Force 1", "nice", 159.99, R.drawable.img_1)
val sneaker2 = Sneaker(null, "Adidas", "ZX 750", "beautiful", 169.99, R.drawable.img_2)
val sneaker3 = Sneaker(null, "Reebok", "Classic", "amazing", 179.99, R.drawable.img_3)
val sneaker4 = Sneaker(null, "Puma", "Classic", "normal", 189.99, R.drawable.img_4)
sneakerDao.insert(sneaker1)
sneakerDao.insert(sneaker2)
sneakerDao.insert(sneaker3)
sneakerDao.insert(sneaker4)
// Order
}
}
fun getInstance(appContext: Context): AppDatabase {
return INSTANCE ?: synchronized(this) {
Room.databaseBuilder(
appContext,
AppDatabase::class.java,
DB_NAME
)
.addCallback(object : Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
CoroutineScope(Dispatchers.IO).launch {
populateDatabase()
}
}
})
.fallbackToDestructiveMigration()
.build()
.also { INSTANCE = it }
}
}
}
}

View File

@ -0,0 +1,27 @@
package com.example.android_programming.model
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity
data class Order(
@PrimaryKey(autoGenerate = true)
val orderId: Int? = null,
@ColumnInfo(name = "Date")
val date: Long,
@ColumnInfo(name = "City")
val city: String,
@ColumnInfo(name = "Street")
val street: String,
@ColumnInfo(name = "House")
val house: String,
@ColumnInfo(name = "Sub Total")
val subtotal: Double,
@ColumnInfo(name = "Taxes")
val taxes: Double,
@ColumnInfo(name = "Total")
val total: Double,
@ColumnInfo(name = "CreatorUserId")
val creatorUserId: Int
)

View File

@ -0,0 +1,9 @@
package com.example.android_programming.model
import androidx.room.Entity
@Entity(primaryKeys = ["orderId", "sneakerId"])
data class OrderSneaker(
val orderId: Int,
val sneakerId: Int
)

View File

@ -0,0 +1,17 @@
package com.example.android_programming.model
import androidx.room.Embedded
import androidx.room.Junction
import androidx.room.Relation
data class OrderWithSneakers(
@Embedded val order: Order,
@Relation(
parentColumn = "orderId",
entityColumn = "sneakerId",
associateBy = Junction(OrderSneaker::class)
)
val sneakers: List<Sneaker>
)

View File

@ -0,0 +1,35 @@
package com.example.android_programming.model
import com.example.android_programming.R
class PhotoManager {
private val photos = listOf(
R.drawable.img,
R.drawable.img_1,
R.drawable.img_2,
R.drawable.img_3,
R.drawable.img_4,
R.drawable.img_5,
)
private var currentIndex = 0
fun changePhoto(int: Int): Int {
currentIndex = photos.indexOf(int)
if (photos.isNotEmpty()) {
if(currentIndex + 1 >= photos.size){
currentIndex = 0
}else{
currentIndex += 1
}
return photos[currentIndex]
} else {
return -1
}
}
}

View File

@ -0,0 +1,6 @@
package com.example.android_programming.model
enum class RoleEnum {
Admin,
User
}

View File

@ -0,0 +1,21 @@
package com.example.android_programming.model
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity
data class Sneaker(
@PrimaryKey(autoGenerate = true)
val sneakerId: Int? = null,
@ColumnInfo(name = "Brand")
val brand: String,
@ColumnInfo(name = "Model")
val model: String,
@ColumnInfo(name = "Description")
val description: String,
@ColumnInfo(name = "Price")
val price: Double,
@ColumnInfo(name = "Photo")
val photo: Int
)

View File

@ -0,0 +1,23 @@
package com.example.android_programming.model
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "users")
data class User(
@PrimaryKey(autoGenerate = true)
val userId: Int? = null,
@ColumnInfo(name = "Name")
val name: String,
@ColumnInfo(name = "Surname")
val surname: String,
@ColumnInfo(name = "Email")
val email: String,
@ColumnInfo(name = "Password")
val password: String,
@ColumnInfo(name = "Role")
val role: RoleEnum,
@ColumnInfo(name = "Photo")
val photo: Int? = null,
)

View File

@ -0,0 +1,13 @@
package com.example.android_programming.model
import androidx.room.Embedded
import androidx.room.Relation
data class UserWithOrder(
@Embedded val user: User,
@Relation(
parentColumn = "userId",
entityColumn = "CreatorUserId"
)
val orders: List<Order>
)

View File

@ -0,0 +1,11 @@
package com.example.android_programming.ui.theme
import androidx.compose.ui.graphics.Color
val Purple80 = Color(0xFFD0BCFF)
val PurpleGrey80 = Color(0xFFCCC2DC)
val Pink80 = Color(0xFFEFB8C8)
val Purple40 = Color(0xFF6650a4)
val PurpleGrey40 = Color(0xFF625b71)
val Pink40 = Color(0xFF7D5260)

View File

@ -0,0 +1,64 @@
//package com.example.android_programming.ui.theme
//
//import android.app.Activity
//import android.os.Build
//import androidx.compose.foundation.isSystemInDarkTheme
//import androidx.compose.material.MaterialTheme
//import androidx.compose.runtime.Composable
//import androidx.compose.runtime.SideEffect
//import androidx.compose.ui.graphics.Color
//import androidx.compose.ui.graphics.toArgb
//import androidx.compose.ui.platform.LocalContext
//import androidx.compose.ui.platform.LocalView
//import androidx.core.view.WindowCompat
//
//private val DarkColorScheme = darkColorScheme(
// primary = Purple80,
// secondary = PurpleGrey80,
// tertiary = Pink80
//)
//
//private val LightColorScheme = lightColorScheme(
// primary = Purple40,
// secondary = PurpleGrey40,
// tertiary = Pink40,
// background = Color(0xFFFFFBFE),
// surface = Color(0xFFFFFBFE),
// onPrimary = Color.White,
// onSecondary = Color.White,
// onTertiary = Color.White,
// onBackground = Color(0xFF1C1B1F),
// onSurface = Color(0xFF1C1B1F),
//)
//
//@Composable
//fun AndroidProgrammingTheme(
// darkTheme: Boolean = isSystemInDarkTheme(),
// // Dynamic color is available on Android 12+
// dynamicColor: Boolean = true,
// content: @Composable () -> Unit
//) {
// val colorScheme = when {
// dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
// val context = LocalContext.current
// if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
// }
//
// darkTheme -> DarkColorScheme
// else -> LightColorScheme
// }
// val view = LocalView.current
// if (!view.isInEditMode) {
// SideEffect {
// val window = (view.context as Activity).window
// window.statusBarColor = colorScheme.primary.toArgb()
// WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme
// }
// }
//
// MaterialTheme(
// colorScheme = colorScheme,
// typography = Typography,
// content = content
// )
//}

View File

@ -0,0 +1,37 @@
/*
package com.example.android_programming.ui.theme
import androidx.compose.material.Typography
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
// Set of Material typography styles to start with
val Typography = Typography(
bodyLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
lineHeight = 24.sp,
letterSpacing = 0.5.sp
)
*/
/* Other default text styles to override
titleLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 22.sp,
lineHeight = 28.sp,
letterSpacing = 0.sp
),
labelSmall = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Medium,
fontSize = 11.sp,
lineHeight = 16.sp,
letterSpacing = 0.5.sp
)
*//*
)*/

View File

@ -0,0 +1,81 @@
package com.example.android_programming.vmodel
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.CreationExtras
import com.example.android_programming.App
import com.example.android_programming.GlobalUser
import com.example.android_programming.database.AppDatabase
import com.example.android_programming.model.Order
import com.example.android_programming.model.OrderSneaker
import com.example.android_programming.model.Sneaker
import kotlinx.coroutines.launch
import java.util.Date
class OrderViewModel(val database: AppDatabase) : ViewModel() {
private var _selectedItems = mutableStateOf<List<Sneaker>>(emptyList())
val selectedItems get() = _selectedItems.value
var city = mutableStateOf("")
val street = mutableStateOf("")
val house = mutableStateOf("")
fun addSelectedItem(item: Sneaker) {
_selectedItems.value = _selectedItems.value + item
}
fun deleteOrder(order: Order) = viewModelScope.launch {
database.orderDao().delete(order)
}
fun getOrderList(id: Int) = viewModelScope.launch {
database.userDao().getUserOrders(id)
}
fun removeSelectedItem(item: Sneaker) {
val updatedItems = _selectedItems.value.toMutableList()
updatedItems.remove(item)
_selectedItems.value = updatedItems
}
fun createOrder() = viewModelScope.launch {
val order = Order(
date = Date().time,
city = city.value,
street = street.value,
house = house.value,
subtotal = getSubTotal(),
taxes = "%.2f".format(getSubTotal() * 0.05).toDouble(),
total = "%.2f".format(getSubTotal() * 0.05 + getSubTotal()).toDouble(),
creatorUserId = GlobalUser.getInstance().getUser()?.userId!!
)
val orderId = database.orderDao().createOrder(order)
for (sneaker in selectedItems) {
val orderSneaker = OrderSneaker( orderId.toInt(), sneaker.sneakerId!!)
database.orderDao().insertOrderSneaker(orderSneaker)
}
city.value = ""
street.value = ""
house.value = ""
_selectedItems = mutableStateOf(emptyList())
}
fun getSubTotal(): Double {
return selectedItems.sumOf { it.price }
}
companion object{
val factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory{
override fun <T : ViewModel> create(
modelClass: Class<T>,
extras: CreationExtras
): T {
val database = (checkNotNull(extras[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY]) as App).database
return OrderViewModel(database) as T
}
}
}
}

View File

@ -0,0 +1,57 @@
package com.example.android_programming.vmodel
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.CreationExtras
import com.example.android_programming.App
import com.example.android_programming.R
import com.example.android_programming.database.AppDatabase
import com.example.android_programming.model.Sneaker
import kotlinx.coroutines.launch
class SneakerViewModel(val database: AppDatabase): ViewModel() {
var brand = mutableStateOf("")
val model = mutableStateOf("")
val description = mutableStateOf("")
val price = mutableStateOf("")
val photo = mutableStateOf(R.drawable.img)
val SneakerList = database.sneakerDao().getAllSneakers()
var sneaker: Sneaker? = null
fun insertSneaker() = viewModelScope.launch {
val sneaker = Sneaker(
brand = brand.value,
model = model.value,
description = description.value,
price = price.value.toDouble(),
photo = photo.value
)
database.sneakerDao().insert(sneaker)
}
fun deleteSneaker(sneaker : Sneaker) = viewModelScope.launch {
database.sneakerDao().delete(sneaker)
}
fun getSneakerById(id: Int) = viewModelScope.launch {
database.sneakerDao().getSneakerById(id)
}
fun UpdateSneaker(sneaker: Sneaker) = viewModelScope.launch {
database.sneakerDao().update(sneaker)
}
companion object{
val factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory{
override fun <T : ViewModel> create(
modelClass: Class<T>,
extras: CreationExtras): T {
val database = (checkNotNull(extras[APPLICATION_KEY]) as App).database
return SneakerViewModel(database) as T
}
}
}
}

View File

@ -0,0 +1,54 @@
package com.example.android_programming.vmodel
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.CreationExtras
import com.example.android_programming.App
import com.example.android_programming.GlobalUser
import com.example.android_programming.database.AppDatabase
import com.example.android_programming.model.RoleEnum
import com.example.android_programming.model.User
import kotlinx.coroutines.launch
class UserViewModel(val database: AppDatabase): ViewModel() {
var name = mutableStateOf("")
val surname = mutableStateOf("")
val email = mutableStateOf("")
val password = mutableStateOf("")
fun createUser() = viewModelScope.launch {
val user = User(
name = name.value,
surname = surname.value,
email = email.value,
password = password.value,
role = RoleEnum.User
)
database.userDao().createUser(user)
}
fun authUser() = viewModelScope.launch {
val user = database.userDao().getUserByEmail(email.value)
if (password.value != "" && user.password == password.value) {
val globalUser = GlobalUser.getInstance()
globalUser.setUser(user)
println()
}
}
fun isValidEmail(email: String): Boolean {
return android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()
}
companion object{
val factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory{
override fun <T : ViewModel> create(
modelClass: Class<T>,
extras: CreationExtras
): T {
val database = (checkNotNull(extras[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY]) as App).database
return UserViewModel(database) as T
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 B

View File

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

View File

@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 693 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 B

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="figma">#F4F4F4</color>
<color name="figma_blue">#3660F6</color>
</resources>

View File

@ -0,0 +1,3 @@
<resources>
<string name="app_name">Android-Programming</string>
</resources>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.AndroidProgramming" parent="android:Theme.Material.Light.NoActionBar" />
</resources>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample backup rules file; uncomment and customize as necessary.
See https://developer.android.com/guide/topics/data/autobackup
for details.
Note: This file is ignored for devices older that API 31
See https://developer.android.com/about/versions/12/backup-restore
-->
<full-backup-content>
<!--
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="device.xml"/>
-->
</full-backup-content>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample data extraction rules file; uncomment and customize as necessary.
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
for details.
-->
<data-extraction-rules>
<cloud-backup>
<!-- TODO: Use <include> and <exclude> to control what is backed up.
<include .../>
<exclude .../>
-->
</cloud-backup>
<!--
<device-transfer>
<include .../>
<exclude .../>
</device-transfer>
-->
</data-extraction-rules>

Some files were not shown because too many files have changed in this diff Show More