Пофиксил

This commit is contained in:
Ismailov_Rovshan 2023-12-14 02:17:19 +04:00
parent 773046a752
commit 1381fe1a37
27 changed files with 774 additions and 189 deletions

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<runningDeviceTargetSelectedWithDropDown>
<Target>
<type value="RUNNING_DEVICE_TARGET" />
<deviceKey>
<Key>
<type value="VIRTUAL_DEVICE_PATH" />
<value value="C:\Users\romai\.android\avd\Pixel_3a_API_34_extension_level_7_x86_64.avd" />
</Key>
</deviceKey>
</Target>
</runningDeviceTargetSelectedWithDropDown>
<targetSelectedWithDropDown>
<Target>
<type value="QUICK_BOOT_TARGET" />
<deviceKey>
<Key>
<type value="VIRTUAL_DEVICE_PATH" />
<value value="C:\Users\romai\.android\avd\Pixel_3a_API_34_extension_level_7_x86_64.avd" />
</Key>
</deviceKey>
</Target>
</targetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2023-12-13T21:04:15.986503500Z" />
</component>
</project>

View File

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

View File

@ -1,6 +1,7 @@
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.devtools.ksp")
}
android {
@ -26,18 +27,19 @@ android {
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "1.8"
jvmTarget = "17"
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.4.3"
kotlinCompilerExtensionVersion = "1.4.5"
}
packaging {
resources {
@ -49,15 +51,24 @@ android {
dependencies {
implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
implementation("androidx.activity:activity-compose:1.7.2")
implementation(platform("androidx.compose:compose-bom:2023.03.00"))
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1")
implementation("androidx.activity:activity-compose:1.7.0")
implementation("androidx.navigation:navigation-compose:2.6.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.material3:material3")
implementation("androidx.navigation:navigation-runtime-ktx:2.7.5")
// Room
val room_version = "2.5.2"
implementation("androidx.room:room-runtime:$room_version")
annotationProcessor("androidx.room:room-compiler:$room_version")
ksp("androidx.room:room-compiler:$room_version")
implementation("androidx.room:room-ktx:$room_version")
implementation("androidx.room:room-paging:$room_version")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")

View File

@ -1,6 +1,5 @@
package com.example.myapplication
import Navbar
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
@ -11,6 +10,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.example.myapplication.navigation.Navbar
import com.example.myapplication.ui.theme.MyApplicationTheme
class MainActivity : ComponentActivity() {

View File

@ -1,25 +1,47 @@
import androidx.compose.foundation.BorderStroke
package com.example.myapplication.components
import ButtonNice
import TextNice
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController
import com.example.myapplication.R
import com.example.myapplication.components.funs.createProductCard
import com.example.myapplication.database.AppDb
import com.example.myapplication.database.entities.Product
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import myColor4
@Composable
fun Cart(navController: NavController, products: List<Product> ){
fun Cart(navController: NavController){
val context = LocalContext.current
val products = remember { mutableStateListOf<Product>() }
val sumPrice = remember { mutableStateOf(0.0) }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
products.clear()
sumPrice.value = 0.0;
AppDb.getInstance(context).userDao().getUserProductCartById(1).products.forEach {
sumPrice.value += it.price
products.add(it)
}
}
}
LazyColumn (contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp)){
item {
TextNice("Корзина")
@ -27,13 +49,13 @@ fun Cart(navController: NavController, products: List<Product> ){
item {
for (product in products){
product.ProductCardInCart()
createProductCard(product.name, product.price, product.img, { } )
}
}
item {
Box(modifier = Modifier.padding(top = 50.dp)){
ButtonNice(text = "Оплатить: 13 898 рублей ", color = myColor4)
}
ButtonNice(text = "Оплатить: " + sumPrice.value.toString() + "Р", color = myColor4)
}
}
}

View File

@ -1,52 +1,90 @@
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
package com.example.myapplication.components
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.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
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.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController
import com.example.myapplication.R
import com.example.myapplication.database.entities.Product
import androidx.compose.runtime.LaunchedEffect
import com.example.myapplication.components.funs.createProductCard
import com.example.myapplication.database.AppDb
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Main(navController: NavController, products: List<Product>) {
Column(
fun Main(navController: NavController, categoryId: Int) {
val context = LocalContext.current
val products = remember { mutableStateListOf<Product>() }
if (categoryId == 0){
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
AppDb.getInstance(context).productDao().getAll().collect { data ->
products.clear()
data.forEach{
products.add(it)
}
}
}
}
} else {
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
AppDb.getInstance(context).categoryDao().getProductsByCategory(categoryId).collect { data ->
products.clear()
data.forEach {
products.add(it)
}
}
}
}
}
LazyColumn(
modifier = Modifier
.fillMaxSize()
.padding(8.dp)
) {
OutlinedTextField(
item { OutlinedTextField(
value = "",
onValueChange = { },
placeholder = { Text("Поиск товара") },
modifier = Modifier
.fillMaxWidth()
.padding(8.dp)
)
Text(
) }
item {Text(
text = "Товары дня:",
fontSize = 28.sp,
color = Color.Black,
modifier = Modifier.padding(8.dp)
)
for (product in products){
product.createProductCard({navController.navigate("product/${product.id}")})
)}
// createProductCard(productById!!.name, productById!!.price, productById!!.img, { } )
item{products.forEach {
createProductCard(it.name, it.price, it.img, { navController.navigate("product/" + it.productId) } )
}
}
}
}

View File

@ -1,3 +1,7 @@
package com.example.myapplication.components
import Input
import TextNice
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@ -58,9 +62,7 @@ fun Registration (navController: NavController){
@Preview(showBackground = true)
@Composable
fun RegistrationPreview() {
// Создаем заглушку для NavController
val navController = rememberNavController()
// Выводим превью компонента
Registration(navController = navController)
}

View File

@ -1,9 +1,18 @@
package com.example.myapplication.components
import ButtonNice
import TextNice
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
@ -11,15 +20,20 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
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 androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController
import com.example.myapplication.R
import myColor2
import myColor3
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun addProduct(navController: NavController) {
Column(modifier = Modifier
Column(
modifier = Modifier
.fillMaxSize().padding(15.dp)
)
{
@ -29,7 +43,6 @@ fun addProduct(navController: NavController){
) {
TextNice("Добавление товара")
}
OutlinedTextField(
value = "",
onValueChange = { },
@ -56,14 +69,32 @@ fun addProduct(navController: NavController){
.padding(top = 5.dp, bottom = 20.dp)
)
ButtonNice(text = "Добавить", color = myColor2, onClickAction = {navController.navigate("category")})
ButtonNice(text = "Отмена", color = Color.White, onClickAction = {navController.navigate("category")})
Button(
onClick = {navController.navigate("addProduct")},
colors = ButtonDefaults.buttonColors(
containerColor= Color.Transparent,
contentColor = myColor3
),
contentPadding = PaddingValues(0.dp),
modifier = Modifier.size(50.dp).padding(top = 10.dp)
) {
Image(
painter = painterResource(id = R.drawable.addphoto),
contentDescription = null,
modifier = Modifier.size(50.dp)
)
}
ButtonNice(
text = "Добавить",
color = myColor2,
onClickAction = { navController.navigate("category") })
ButtonNice(
text = "Отмена",
color = Color.White,
onClickAction = { navController.navigate("category") })
}
}
@Preview(showBackground = true)
@Composable
fun addPage() {
val navController = rememberNavController()
addProduct(navController = navController)
}

View File

@ -0,0 +1,76 @@
package com.example.myapplication.components.funs
import ButtonNice
import TextNice
import android.graphics.Bitmap
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import myColor1
import myColor4
@Composable
fun createProductCard(name: String, price: Double, img: Bitmap, onClickAction: () -> Unit){
Column () {
Row {
Image(
bitmap = img.asImageBitmap(),
contentDescription = null,
modifier = Modifier.size(150.dp)
)
Column (modifier = Modifier.padding(start = 15.dp, end = 15.dp)){
Text(name, fontSize = 24.sp, color = Color.Black)
Text(price.toString() + "", fontSize = 16.sp, color = Color.Black)
ButtonNice("Инфо: " , Color.White, onClickAction)
}
}
ButtonNice("Добавить в корзину" , myColor1, onClickAction)
}
}
@Composable
fun createProductPage(name: String,info: String,price: Int, @DrawableRes imgId: Int, onClickAction: () -> Unit){
LazyColumn (modifier = Modifier.fillMaxSize().padding(10.dp)) {
item{
Box(
modifier = Modifier.padding(bottom = 10.dp).fillMaxWidth(),
contentAlignment = Alignment.Center
){
TextNice(name)
}
}
item {
Image(
painter = painterResource(id = imgId),
contentDescription = null,
modifier = Modifier
.size(400.dp)
.aspectRatio(1f)
)
}
item{TextNice("Характеристики: ")}
item{Text(info) }
item{ButtonNice("Добавить в корзину", myColor4, onClickAction )}
}
}

View File

@ -1,3 +1,6 @@
package com.example.myapplication.components.templates
import ButtonNice
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color

View File

@ -1,38 +1,27 @@
import androidx.compose.foundation.BorderStroke
package com.example.myapplication.components.templates
import TextNice
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController
import com.example.myapplication.R
import com.example.myapplication.components.funs.createProductCard
import com.example.myapplication.database.entities.Product
import com.example.myapplication.product.ProductOld
import myColor3
@Composable
fun CatalogItems (navController: NavController, title: String, products: List<Product>){
fun CatalogItems (navController: NavController, title: String, products: MutableList<Product>){
LazyColumn (
contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp),
@ -42,7 +31,7 @@ fun CatalogItems (navController: NavController, title: String, products: List<Pr
}
item{
for (product in products){
product.createProductCard({navController.navigate("product/${product.id}")})
createProductCard(product.name, product.price, product.img, { })
}
}
item {

View File

@ -1,38 +1,26 @@
import android.graphics.Bitmap
import androidx.annotation.DrawableRes
import androidx.compose.foundation.BorderStroke
package com.example.myapplication.components.templates
import ButtonNice
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.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.graphics.RectangleShape
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController
import com.example.myapplication.R
import com.example.myapplication.product.ProductOld
import myColor1
@Composable
fun ProductCard(product: Product, onClickAction: () -> Unit) {
fun ProductCard(product: ProductOld, onClickAction: () -> Unit) {
Column (modifier = Modifier.padding(top = 20.dp, start = 10.dp, end=10.dp)) {
Row {
Image(

View File

@ -1,3 +1,6 @@
package com.example.myapplication.components.templates
import TextNice
import androidx.annotation.DrawableRes
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image

View File

@ -0,0 +1,30 @@
package com.example.myapplication.components.templates
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import com.example.myapplication.database.AppDb
import com.example.myapplication.database.entities.Product
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@Composable
fun ProductForPage(id: Int) {
val context = LocalContext.current
val (product, setProduct) = remember { mutableStateOf<Product?>(null) } //спросить
LaunchedEffect(Unit) {
withContext(Dispatchers.IO){
AppDb.getInstance(context).productDao().getById(id).collect {
setProduct(it)
}
}
}
if (product != null){
ProductPage(product!!.name, product!!.info, product!!.price, product!!.img, { } )
}
}

View File

@ -1,3 +1,8 @@
package com.example.myapplication.components.templates
import ButtonNice
import TextNice
import android.graphics.Bitmap
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
@ -11,15 +16,17 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController
import com.example.myapplication.R
import myColor4
@Composable
fun ProductPage(name: String,info: String, price: Int, @DrawableRes imgId: Int, onClickAction: () -> Unit){
fun ProductPage(name: String, info: String, price: Double, img: Bitmap, onClickAction: () -> Unit){
LazyColumn (modifier = Modifier.fillMaxSize().padding(10.dp)) {
item{
@ -27,33 +34,16 @@ fun ProductPage(name: String,info: String, price: Int, @DrawableRes imgId: Int,
}
item {
Image(
painter = painterResource(id = imgId),
bitmap = img.asImageBitmap(),
contentDescription = null,
modifier = Modifier
.size(400.dp)
.aspectRatio(1f)
)}
modifier = Modifier.size(150.dp)
)
}
item{TextNice("Характеристики: ")}
item{Text(info)}
item{ButtonNice("Добавить в корзину", myColor4, onClickAction )}
}
}
@Preview
@Composable
fun ProductPagePreview(){
val navController = rememberNavController()
ProductPage("MSI GeForce RTX 4090 VENTUS 3X OC" ,"Общая информация: Дата выхода на рынок 2022 г.\n" +
"Основные характеристики: Подбор в один клик с трассировкой лучей, для игр в 4K, для рендеринга, профессиональная\n" +
"Интерфейс: PCI Express x16 4.0\n" +
"Производитель графического процессора: NVIDIA\n" +
"Микроархитектура: NVIDIA Ada Lovelace\n" +
"Кодовое имя чипа: AD102\n" +
"Графический процессор: GeForce RTX 4090\n" +
"«Разогнанная» версия: Нет\n" +
"Трассировка лучей: Да\n" +
"Защита от майнинга (LHR): Нет\n" +
"Внешняя видеокарта: Нет",15000, R.drawable.product1, onClickAction = { navController.navigate("main") })
}

View File

@ -1,28 +1,75 @@
package com.example.myapplication.components
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController
import com.example.myapplication.components.templates.CatalogItems
import com.example.myapplication.components.templates.CategoryItem
import com.example.myapplication.database.AppDb
import com.example.myapplication.database.entities.Category
import com.example.myapplication.database.entities.Product
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@Composable
fun Сategory(navController: NavController) {
Column(modifier = Modifier.fillMaxWidth().padding(start = 10.dp, end = 10.dp, top = 20.dp, ),
Column(
modifier = Modifier.fillMaxWidth().padding(start = 10.dp, end = 10.dp, top = 20.dp,),
horizontalAlignment = Alignment.End
) {
CategoryItem(text = "Процессоры", { navController.navigate("processors") })
CategoryItem(text = "Видеокарты", { navController.navigate("videocards") })
val context = LocalContext.current
val categories = remember { mutableStateListOf<Category>() }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
AppDb.getInstance(context).categoryDao().getAll().collect { data ->
categories.clear()
data.forEach {
categories.add(it)
}
}
}
}
categories.forEach{
CategoryItem(it.name, { navController.navigate("main/" + it.id)})
}
CategoryItem(text = "ПЗУ", { navController.navigate("processors") })
CategoryItem(text = "ОЗУ", { navController.navigate("processors") })
}
}
@Preview(showBackground = true)
@Composable
fun CatalogPreview() {
fun myFun(categoryId: Int, title: String){
val navController = rememberNavController()
val context = LocalContext.current
val products = remember { mutableStateListOf<Product>() }
LaunchedEffect(Unit) {
withContext(Dispatchers.IO) {
AppDb.getInstance(context).categoryDao().getProductsByCategory(categoryId).collect { data ->
products.clear()
data.forEach {
products.add(it)
}
}
}
}
CatalogItems(navController, title, products )
}

View File

@ -0,0 +1,125 @@
package com.example.myapplication.database
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import androidx.sqlite.db.SupportSQLiteDatabase
import com.example.myapplication.R
import com.example.myapplication.database.dao.CategoryDao
import com.example.myapplication.database.dao.ProductDao
import com.example.myapplication.database.dao.UserDao
import com.example.myapplication.database.entities.Category
import com.example.myapplication.database.entities.Converters
import com.example.myapplication.database.entities.Product
import com.example.myapplication.database.entities.User
import com.example.myapplication.database.entities.UserProductCart
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@Database(entities = [User::class, Product::class, Category:: class, UserProductCart::class], version = 1, exportSchema = false)
@TypeConverters(Converters::class)
abstract class AppDb: RoomDatabase(){
abstract fun userDao(): UserDao
abstract fun productDao(): ProductDao
abstract fun categoryDao(): CategoryDao
companion object {
private const val DB_NAME: String = "myApp2.db"
@Volatile
private var INSTANCE: AppDb? = null
private suspend fun populateDatabase(context: Context) {
INSTANCE?.let { database ->
val categoryDao = database.categoryDao()
categoryDao.insert(Category(1, "Видеокарты"))
categoryDao.insert(Category(2, "Процессоры"))
categoryDao.insert(Category(3, "Оперативная память"))
categoryDao.insert(Category(4, "Твердотельные накопители"))
val productDao = database.productDao()
val img1: Bitmap = BitmapFactory.decodeResource(context.resources, R.drawable.product1)
val img2: Bitmap = BitmapFactory.decodeResource(context.resources, R.drawable.product2)
val img3: Bitmap = BitmapFactory.decodeResource(context.resources, R.drawable.product3)
val img4: Bitmap = BitmapFactory.decodeResource(context.resources, R.drawable.product4)
val img5: Bitmap = BitmapFactory.decodeResource(context.resources, R.drawable.product5)
val img6: Bitmap = BitmapFactory.decodeResource(context.resources, R.drawable.product6)
val img7: Bitmap = BitmapFactory.decodeResource(context.resources, R.drawable.product7)
val img8: Bitmap = BitmapFactory.decodeResource(context.resources, R.drawable.product8)
productDao.insert(Product(1, "MSI GeForce RTX 4090 VENTUS 3X OC",
"Информацио о товаре MSI GeForce RTX 4090 VENTUS 3X OC ",
210999.0, img1, 1
))
productDao.insert(Product(2, "Palit GeForce GTX 1660 SUPER",
"Информацио о товаре Palit GeForce GTX 1660 SUPER ",
25999.0, img2, 1
))
productDao.insert(Product(3, "Intel Celeron G5905 OEM",
"Информацио о товаре Intel Celeron G5905 OEM ",
25999.0, img3, 2
))
productDao.insert(Product(4, "AMD Ryzen 5 4500 BOX",
"Информацио о товаре Intel Celeron G5905 OEM",
9799.0, img4, 2
))
productDao.insert(Product(5, "Kingston FURY Beast Black",
"Информацио о товаре Kingston FURY Beast Black",
4499.0, img5, 3
))
productDao.insert(Product(6, "ADATA XPG SPECTRIX D41 RGB",
"Информацио о товаре ADATA XPG SPECTRIX D41 RGB",
4599.0, img6, 3
))
productDao.insert(Product(7, "ADATA SU650",
"Информацио о товаре ADATA SU650",
1550.0, img7, 4
))
productDao.insert(Product(8, "Smartbuy Revival 3",
"Информацио о товаре Smartbuy Revival 3",
1250.0, img8, 4
))
val userDao = database.userDao()
userDao.insert(User(1, "Иванов И.И", "ivanov"))
database.userDao().addProductCart(UserProductCart(1, 1))
database.userDao().addProductCart(UserProductCart(1, 3))
//database.userDao().addProductCart(UserProductCart(1, 2))
}
}
fun getInstance(appContext: Context): AppDb {
return INSTANCE ?: synchronized(this) {
Room.databaseBuilder(
appContext,
AppDb::class.java,
DB_NAME
)
.addCallback(object : Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
CoroutineScope(Dispatchers.IO).launch {
populateDatabase(appContext)
}
}
})
.build()
.also { INSTANCE = it }
}
}
}
}

View File

@ -0,0 +1,19 @@
package com.example.myapplication.database.dao
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import com.example.myapplication.database.entities.Category
import com.example.myapplication.database.entities.Product
import kotlinx.coroutines.flow.Flow
@Dao
interface CategoryDao {
@Query("select * from categories")
fun getAll(): Flow<List<Category>>
@Insert
suspend fun insert(category: Category)
@Query("select * from products where category_id = :categoryId")
fun getProductsByCategory(categoryId: Int): Flow<List<Product>>
}

View File

@ -0,0 +1,27 @@
package com.example.myapplication.database.dao;
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import com.example.myapplication.database.entities.User
import com.example.myapplication.database.entities.UserProductCart
import com.example.myapplication.database.entities.UserWithCartProduct
import kotlinx.coroutines.flow.Flow
@Dao
interface UserDao {
@Query("select * from users")
fun getAll(): Flow<List<User>>
@Query("select * from users where users.userId = :id")
fun getById(id: Int): User
@Insert
suspend fun insert(user: User)
@Query("select * from users where users.userId = :id")
fun getUserProductCartById(id: Int): UserWithCartProduct
@Insert
suspend fun addProductCart(userProduct: UserProductCart)
}

View File

@ -0,0 +1,26 @@
package com.example.myapplication.database.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "categories")
data class Category(
@PrimaryKey(autoGenerate = true)
var id: Int?,
@ColumnInfo(name="name")
val name: String
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Category
if (id != other.id) return false
return true
}
override fun hashCode(): Int {
return id ?: -1
}
}

View File

@ -0,0 +1,19 @@
package com.example.myapplication.database.entities
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import androidx.room.TypeConverter
import java.io.ByteArrayOutputStream
class Converters {
@TypeConverter
fun fromBitmap(bitmap: Bitmap) : ByteArray {
val outputStream = ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
return outputStream.toByteArray()
}
@TypeConverter
fun toBitmap(byteArray: ByteArray): Bitmap {
return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size)
}
}

View File

@ -0,0 +1,59 @@
package com.example.myapplication.database.entities
import android.graphics.Bitmap
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.PrimaryKey
@Entity(
tableName = "products",
foreignKeys = [
ForeignKey(
entity = Category::class,
parentColumns = ["id"],
childColumns = ["category_id"],
onDelete = ForeignKey.RESTRICT,
onUpdate = ForeignKey.RESTRICT
)
]
)
data class Product(
@PrimaryKey(autoGenerate = true)
var productId: Int?,
@ColumnInfo(name="name")
val name: String,
@ColumnInfo(name="info")
val info: String,
@ColumnInfo(name="price")
val price: Double,
@ColumnInfo(name="img")
val img: Bitmap,
@ColumnInfo(name="category_id")
val categoryId: Int
){
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Product
if (productId != other.productId) return false
return true
}
override fun hashCode(): Int {
return productId ?: -1
}
}

View File

@ -0,0 +1,27 @@
package com.example.myapplication.database.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "users")
data class User(
@PrimaryKey(autoGenerate = true)
var userId: Int?,
@ColumnInfo(name="name")
val name: String,
@ColumnInfo(name="login")
val login: String
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as User
if (userId != other.userId) return false
return true
}
override fun hashCode(): Int {
return userId ?: -1
}
}

View File

@ -0,0 +1,15 @@
package com.example.myapplication.database.entities
import androidx.room.Embedded
import androidx.room.Junction
import androidx.room.Relation
data class UserWithCartProduct (
@Embedded val user : User,
@Relation(
parentColumn = "userId",
entityColumn = "productId",
associateBy = Junction(UserProductCart::class)
)
val products : List<Product>
)

View File

@ -1,3 +1,5 @@
package com.example.myapplication.navigation
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
@ -20,7 +22,13 @@ import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.example.myapplication.R
import com.example.myapplication.navigation.NavItem
import com.example.myapplication.components.Authorization
import com.example.myapplication.components.Cart
import com.example.myapplication.components.Main
import com.example.myapplication.components.Registration
import com.example.myapplication.components.myFun
import com.example.myapplication.components.templates.ProductForPage
import com.example.myapplication.components.Сategory
import com.example.myapplication.ui.theme.MyApplicationTheme
@OptIn(ExperimentalMaterial3Api::class)
@ -28,22 +36,22 @@ import com.example.myapplication.ui.theme.MyApplicationTheme
fun Navbar() {
val navController = rememberNavController()
val items = listOf(
NavItem("main", "Главная", R.drawable.home),
NavItem("main/0", "Главная", R.drawable.home),
NavItem("category", "Каталог", R.drawable.search),
NavItem("cart", "Корзина", R.drawable.cart),
)
val videocars = listOf(
Product(3, "MSI GeForce RTX 4090 VENTUS 3X OC", "Видеокарта MSI GeForce RTX 4090 VENTUS 3X OC создана для игровых ПК и профессиональных рабочих станций. Благодаря архитектуре NVIDIA Ada Lovelace она обеспечивает мощный вычислительный потенциал и плавность отображения динамичной графики без задержек. Тактовая частота процессора составляет 2230 МГц и способна увеличиваться до 2565 МГц при разгоне. Видеокарта оснащена 24 ГБ выделенной памяти стандарта GDDR6X.\n" +
"Вывод изображения на внешние мониторы может выполняться посредством 3 разъемов DisplayPort и 1 HDMI. Три вентилятора совместно с радиатором и тепловыми трубками быстро рассеивают тепло и поддерживают низкую температуру нагрева. Усиленная подсистема питания и отборные компоненты гарантируют стабильность работы MSI GeForce RTX 4090 VENTUS 3X ОС. Защитная пластина на тыловой стороне делает видеокарту устойчивой к деформации и механическим воздействиям. Фирменное приложение MSI Center позволяет выполнять мониторинг и настраивать параметры графического адаптера.", 210999, R.drawable.product1),
Product(4, "Palit GeForce GTX 1660 SUPER", "Видеокарта Palit GeForce GTX 1660 SUPER Gaming Pro [NE6166S018J9-1160A-1] представляет собой производительное решение в компактном корпусе, которое станет отличным выбором для компьютерных систем в миниатюрном корпусе. В основе графического ускорителя используется многоядерный процессор, работающий в широком частотном диапазоне, что вкупе с большим объемом встроенной памяти может обеспечить комфортную работу практически с любыми задачами. Максимальная температура ускорителя при этом может достигать отметки 93°C, для отвода тепла используется несколько осевых вентиляторов.\n" +
"Графический ускоритель Palit GeForce GTX 1660 SUPER Gaming Pro также отличается строгим дизайном, благодаря чему легко сможет дополнить собой практически любую сборку. Длина данной модели не превышает 235 мм, а толщина 42 мм, благодаря чему для установки задействуется всего 2 отсека расширения. Для подключения к материнской плате используется интерфейс PCI-E 3.0. Для внешних мониторов на корпусе также предусмотрено несколько видов видеоразъемов.", 25999, R.drawable.product2),
)
val processors = listOf(
Product(1, "Intel Celeron G5905 OEM", "Процессор Intel Celeron G5905 представляет собой 2-ядерный чипсет начального уровня, подходящий для сборки домашнего или офисного компьютера. Созданная на базе архитектуры Intel Comet Lake-S модель использует 14-нанометровый техпроцесс, благодаря которому обеспечивается оптимальное сочетание производительности и энергопотребления. Для установки чипсета на материнскую плату используется популярный сокет LGA 1200. В работе устройство использует 2 производительных ядра, способных одновременно обрабатывать два вычислительных потока.\n" +
"Процессор Intel Celeron G5905 функционирует на фиксированной тактовой частоте 3.5 ГГц. В данной модели предусмотрено интегрированное графическое ядро Intel UHD Graphics 610, которому под силу справиться с обработкой нересурсоемкой графики и ее выводом на экран монитора.", 4099, R.drawable.product3),
Product(2, "AMD Ryzen 5 4500 BOX", "Шестиядерный процессор AMD Ryzen 5 4500 BOX основан на архитектуре Zen 2 и выполнен по техпроцессу TSMC 7FF. Устройство имеет базовую тактовую частоту 3.6 ГГц и максимальную 4.1 ГГц. Он также поддерживает технологии Simultaneous Multithreading (SMT) и Precision Boost, позволяющие эффективно использовать все 6 ядер процессора.\n" +
"AMD Ryzen 5 4500 BOX обладает высокими показателями производительности, особенно в многозадачных сценариях. Он также имеет низкое потребление энергии, что позволяет создавать энергоэффективные системы. Процессор поддерживает стандартную сокетную платформу AM4 и может быть установлен на совместимые материнские платы.", 9799, R.drawable.product4),
)
// val videocars = listOf(
// Product(3, "MSI GeForce RTX 4090 VENTUS 3X OC", "Видеокарта MSI GeForce RTX 4090 VENTUS 3X OC создана для игровых ПК и профессиональных рабочих станций. Благодаря архитектуре NVIDIA Ada Lovelace она обеспечивает мощный вычислительный потенциал и плавность отображения динамичной графики без задержек. Тактовая частота процессора составляет 2230 МГц и способна увеличиваться до 2565 МГц при разгоне. Видеокарта оснащена 24 ГБ выделенной памяти стандарта GDDR6X.\n" +
// "Вывод изображения на внешние мониторы может выполняться посредством 3 разъемов DisplayPort и 1 HDMI. Три вентилятора совместно с радиатором и тепловыми трубками быстро рассеивают тепло и поддерживают низкую температуру нагрева. Усиленная подсистема питания и отборные компоненты гарантируют стабильность работы MSI GeForce RTX 4090 VENTUS 3X ОС. Защитная пластина на тыловой стороне делает видеокарту устойчивой к деформации и механическим воздействиям. Фирменное приложение MSI Center позволяет выполнять мониторинг и настраивать параметры графического адаптера.", 210999, R.drawable.product1),
// Product(4, "Palit GeForce GTX 1660 SUPER", "Видеокарта Palit GeForce GTX 1660 SUPER Gaming Pro [NE6166S018J9-1160A-1] представляет собой производительное решение в компактном корпусе, которое станет отличным выбором для компьютерных систем в миниатюрном корпусе. В основе графического ускорителя используется многоядерный процессор, работающий в широком частотном диапазоне, что вкупе с большим объемом встроенной памяти может обеспечить комфортную работу практически с любыми задачами. Максимальная температура ускорителя при этом может достигать отметки 93°C, для отвода тепла используется несколько осевых вентиляторов.\n" +
// "Графический ускоритель Palit GeForce GTX 1660 SUPER Gaming Pro также отличается строгим дизайном, благодаря чему легко сможет дополнить собой практически любую сборку. Длина данной модели не превышает 235 мм, а толщина 42 мм, благодаря чему для установки задействуется всего 2 отсека расширения. Для подключения к материнской плате используется интерфейс PCI-E 3.0. Для внешних мониторов на корпусе также предусмотрено несколько видов видеоразъемов.", 25999, R.drawable.product2),
// )
// val processors = listOf(
// Product(1, "Intel Celeron G5905 OEM", "Процессор Intel Celeron G5905 представляет собой 2-ядерный чипсет начального уровня, подходящий для сборки домашнего или офисного компьютера. Созданная на базе архитектуры Intel Comet Lake-S модель использует 14-нанометровый техпроцесс, благодаря которому обеспечивается оптимальное сочетание производительности и энергопотребления. Для установки чипсета на материнскую плату используется популярный сокет LGA 1200. В работе устройство использует 2 производительных ядра, способных одновременно обрабатывать два вычислительных потока.\n" +
// "Процессор Intel Celeron G5905 функционирует на фиксированной тактовой частоте 3.5 ГГц. В данной модели предусмотрено интегрированное графическое ядро Intel UHD Graphics 610, которому под силу справиться с обработкой нересурсоемкой графики и ее выводом на экран монитора.", 4099, R.drawable.product3),
// Product(2, "AMD Ryzen 5 4500 BOX", "Шестиядерный процессор AMD Ryzen 5 4500 BOX основан на архитектуре Zen 2 и выполнен по техпроцессу TSMC 7FF. Устройство имеет базовую тактовую частоту 3.6 ГГц и максимальную 4.1 ГГц. Он также поддерживает технологии Simultaneous Multithreading (SMT) и Precision Boost, позволяющие эффективно использовать все 6 ядер процессора.\n" +
// "AMD Ryzen 5 4500 BOX обладает высокими показателями производительности, особенно в многозадачных сценариях. Он также имеет низкое потребление энергии, что позволяет создавать энергоэффективные системы. Процессор поддерживает стандартную сокетную платформу AM4 и может быть установлен на совместимые материнские платы.", 9799, R.drawable.product4),
// )
Scaffold(
bottomBar = {
@ -77,23 +85,26 @@ fun Navbar() {
composable("authorization") { Authorization(navController) }
composable("registration") { Registration(navController) }
composable("main") { Main(navController, processors) }
composable("category") { Сategory(navController) }
composable("cart") { Cart(navController, processors) }
//composable("main") { Main(navController) }
composable("processors") { CatalogItems(navController, "Процессоры", processors) }
composable("videocards") { CatalogItems(navController, "Видеокарты", videocars) }
composable("addProduct") { addProduct(navController) }
composable("product/{id}",
composable(
"main/{id}",
arguments = listOf(navArgument("id") { type = NavType.IntType })
)
{ backStackEntry ->
) { backStackEntry ->
backStackEntry.arguments?.let {
Product(it.getInt("id")).createProductPage {
Main(navController, it.getInt("id"))
}
}
composable("category") { Сategory(navController) }
composable("cart") { Cart(navController) }
composable(
"product/{id}",
arguments = listOf(navArgument("id") { type = NavType.IntType })
) { backStackEntry ->
backStackEntry.arguments?.let { ProductForPage(it.getInt("id")) }
}
}
}
@ -104,7 +115,6 @@ fun Navbar() {
@Composable
fun PreviewNavbar() {
MyApplicationTheme {
// A surface container using the 'background' color from the theme
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
Navbar()
}

View File

@ -1,4 +1,3 @@
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
val myColor1 = Color(0, 153, 153, 255)

View File

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