бета аналитика ver 0.1

This commit is contained in:
Данила Мочалов 2023-12-26 14:32:54 +04:00
parent c1b7f45b2c
commit da80721cd1
11 changed files with 247 additions and 26 deletions

View File

@ -1,17 +0,0 @@
<?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\Danya\.android\avd\Nexus_5X_API_34_3.avd" />
</Key>
</deviceKey>
</Target>
</runningDeviceTargetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2023-12-25T13:14:56.067510100Z" />
</component>
</project>

View File

@ -52,7 +52,7 @@ object AppModule {
@Provides @Provides
@Singleton @Singleton
fun provideProductRepository(db: AppDatabase, restProductRepository: RestProductRepository) : ProductRepository { fun provideProductRepository(db: AppDatabase, restProductRepository: RestProductRepository) : ProductRepository {
return ProductRepository(database = db, db.productDao(), db.orderProductDao(), restProductRepository) return ProductRepository(database = db, db.productDao(), restProductRepository)
} }
@Provides @Provides

View File

@ -19,6 +19,7 @@ import retrofit2.http.Header
import retrofit2.http.POST import retrofit2.http.POST
import retrofit2.http.PUT import retrofit2.http.PUT
import retrofit2.http.Path import retrofit2.http.Path
import retrofit2.http.Query
interface MyServerService { interface MyServerService {
@ -110,6 +111,14 @@ interface MyServerService {
@POST("order/product/delete") @POST("order/product/delete")
suspend fun deleteOrderProduct(@Body orderProduct: OrderProductRemote, @Header("Authorization") token: String) suspend fun deleteOrderProduct(@Body orderProduct: OrderProductRemote, @Header("Authorization") token: String)
//
// COURSEWORK ANALYSIS
//
@GET("analysis/products")
suspend fun getTopProducts(@Query("period") period : String, @Header("Authorization") token: String) : List<ProductModelRemote>
companion object { companion object {
private const val BASE_URL = "https://10.0.2.2:80/api/" private const val BASE_URL = "https://10.0.2.2:80/api/"

View File

@ -1,6 +1,7 @@
package com.example.shawarma.data.api.repos package com.example.shawarma.data.api.repos
import com.example.shawarma.data.api.MyServerService import com.example.shawarma.data.api.MyServerService
import com.example.shawarma.data.api.models.ProductModelRemote
import com.example.shawarma.data.api.models.toProductModelRemote import com.example.shawarma.data.api.models.toProductModelRemote
import com.example.shawarma.data.models.ProductModel import com.example.shawarma.data.models.ProductModel
import javax.inject.Inject import javax.inject.Inject
@ -19,4 +20,8 @@ class RestProductRepository @Inject constructor(
suspend fun delete(id: Int, token: String) { suspend fun delete(id: Int, token: String) {
service.deleteProduct(id, token) service.deleteProduct(id, token)
} }
suspend fun getTopProducts(period: String, token: String) : List<ProductModelRemote> {
return service.getTopProducts(period, token)
}
} }

View File

@ -6,9 +6,9 @@ import androidx.paging.PagingConfig
import androidx.paging.PagingData import androidx.paging.PagingData
import com.example.shawarma.data.api.MyServerService import com.example.shawarma.data.api.MyServerService
import com.example.shawarma.data.api.mediators.ProductRemoteMediator import com.example.shawarma.data.api.mediators.ProductRemoteMediator
import com.example.shawarma.data.api.models.toProductModel
import com.example.shawarma.data.api.repos.RestProductRepository import com.example.shawarma.data.api.repos.RestProductRepository
import com.example.shawarma.data.db.AppDatabase import com.example.shawarma.data.db.AppDatabase
import com.example.shawarma.data.interfaces.dao.OrderProductDao
import com.example.shawarma.data.interfaces.dao.ProductDao import com.example.shawarma.data.interfaces.dao.ProductDao
import com.example.shawarma.data.models.ProductModel import com.example.shawarma.data.models.ProductModel
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@ -17,7 +17,6 @@ import javax.inject.Inject
class ProductRepository @Inject constructor( class ProductRepository @Inject constructor(
private val database: AppDatabase, private val database: AppDatabase,
private val productDao: ProductDao, private val productDao: ProductDao,
private val orderProductDao: OrderProductDao,
private val restRepository: RestProductRepository private val restRepository: RestProductRepository
) { ) {
suspend fun insert(product: ProductModel, token: String) { suspend fun insert(product: ProductModel, token: String) {
@ -63,4 +62,8 @@ class ProductRepository @Inject constructor(
remoteMediator = ProductRemoteMediator(database = database, serverService = MyServerService.getInstance(), query = "items", token = token) remoteMediator = ProductRemoteMediator(database = database, serverService = MyServerService.getInstance(), query = "items", token = token)
).flow ).flow
suspend fun getTopProducts(period: String, token: String) : List<ProductModel> {
return restRepository.getTopProducts(period, token).map { it.toProductModel() }
}
} }

View File

@ -2,9 +2,7 @@ package com.example.shawarma.screens
import android.annotation.SuppressLint import android.annotation.SuppressLint
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Scaffold import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -20,6 +18,7 @@ import com.example.shawarma.screens.discount.DiscountScreen
import com.example.shawarma.screens.home.HomeScreen import com.example.shawarma.screens.home.HomeScreen
import com.example.shawarma.screens.orders.OrdersScreen import com.example.shawarma.screens.orders.OrdersScreen
import com.example.shawarma.screens.products.ProductScreen import com.example.shawarma.screens.products.ProductScreen
import com.example.shawarma.screens.products.ProductsAnalysis
import com.example.shawarma.screens.products.ProductsScreen import com.example.shawarma.screens.products.ProductsScreen
import com.example.shawarma.screens.registration.RegistrationScreen import com.example.shawarma.screens.registration.RegistrationScreen
import com.example.shawarma.ui.theme.MyLightYellow import com.example.shawarma.ui.theme.MyLightYellow
@ -77,6 +76,9 @@ fun MainNavBar() {
val productId = navBackStackEntry.arguments?.getInt("productId") val productId = navBackStackEntry.arguments?.getInt("productId")
ProductScreen(navController, productId) ProductScreen(navController, productId)
} }
composable(ScreenPaths.analysis.name){
ProductsAnalysis()
}
} }
} }
} }

View File

@ -160,6 +160,6 @@ fun ProductWidget(navHostController: NavHostController, productId: Int?) {
) )
} }
} }
}
}
}
}

View File

@ -0,0 +1,190 @@
package com.example.shawarma.screens.products
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Card
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.livedata.observeAsState
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.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.zIndex
import androidx.hilt.navigation.compose.hiltViewModel
import com.example.shawarma.data.models.ProductModel
import com.example.shawarma.data.sharedpref.PreferencesManager
import com.example.shawarma.ui.theme.MarckFamily
import com.example.shawarma.ui.theme.MyLightYellow
import com.example.shawarma.ui.theme.MyMainBackground
import com.example.shawarma.ui.theme.MyOrange
import com.example.shawarma.ui.theme.NunitoFamily
import com.example.shawarma.viewmodels.ProductsViewModel
import com.example.shawarma.widgets.ShawarmaLogo2
@Composable
fun ProductsAnalysis() {
val productsViewModel: ProductsViewModel = hiltViewModel<ProductsViewModel>()
Box(
contentAlignment = Alignment.TopCenter
) {
TopProductsWidget(productsViewModel)
ShawarmaLogo2()
}
}
@Composable
fun TopProductsWidget(productsViewModel: ProductsViewModel) {
val preferencesManager = PreferencesManager(LocalContext.current)
val searchToken = preferencesManager.getData("token", "")
val topProductsList = productsViewModel.topProductList.observeAsState().value
Box(
modifier = Modifier
.clip(shape = RoundedCornerShape(30.dp))
.padding(top = 100.dp)
.fillMaxSize()
.background(color = MyMainBackground)
.zIndex(2f),
contentAlignment = Alignment.TopCenter
){
Text(
text = "Аналитика",
fontFamily = MarckFamily,
fontSize = 40.sp,
modifier = Modifier.padding(top = 15.dp)
)
Row(
modifier = Modifier
.fillMaxHeight()
.padding(top = 60.dp)
){
Button(
modifier = Modifier
.fillMaxWidth(0.33f)
.weight(1f),
colors = ButtonDefaults.buttonColors(
backgroundColor = MyLightYellow
),
border = BorderStroke(2.dp, color = MyOrange),
shape = RoundedCornerShape(20.dp),
onClick = {
productsViewModel.getTopProductsList(searchToken, "week")
}
) {
Text(text = "Неделя")
}
Button(
modifier = Modifier
.fillMaxWidth(0.33f)
.weight(1f),
colors = ButtonDefaults.buttonColors(
backgroundColor = MyLightYellow
),
border = BorderStroke(2.dp, color = MyOrange),
shape = RoundedCornerShape(20.dp),
onClick = {
productsViewModel.getTopProductsList(searchToken, "month")
}
) {
Text(text = "Месяц")
}
Button(
modifier = Modifier
.fillMaxWidth(0.33f)
.weight(1f),
colors = ButtonDefaults.buttonColors(
backgroundColor = MyLightYellow
),
border = BorderStroke(2.dp, color = MyOrange),
shape = RoundedCornerShape(20.dp),
onClick = {
productsViewModel.getTopProductsList(searchToken, "year")
}
) {
Text(text = "Год")
}
}
if (!topProductsList.isNullOrEmpty()) {
LazyColumn(
modifier = Modifier.padding(top = 120.dp, bottom = 60.dp),
){
items(
topProductsList.size
) {
TopProductItem(topProductsList[it])
Spacer(modifier = Modifier.size(20.dp))
}
}
}
}
}
@Composable
fun TopProductItem(product: ProductModel){
Card(
border = BorderStroke(width = 2.dp, color = MyOrange),
shape = RoundedCornerShape(size = 20.dp),
backgroundColor = Color.White,
modifier = Modifier.size(340.dp, 100.dp)
) {
Row(
modifier = Modifier
.padding(20.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceAround
) {
Column(
modifier = Modifier.fillMaxWidth(1f)
) {
Text(
text = product.title,
fontFamily = NunitoFamily,
fontSize = 20.sp,
fontWeight = FontWeight.Bold,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
if (product.oldPrice != null) {
Text(
text = product.price.toString() + " руб.",
fontFamily = NunitoFamily,
fontSize = 20.sp,
fontWeight = FontWeight.Bold,
color = Color.Red
)
}
else {
Text(
text = product.price.toString() + " руб.",
fontFamily = NunitoFamily,
fontSize = 20.sp,
fontWeight = FontWeight.Bold
)
}
}
}
}
}

View File

@ -103,9 +103,29 @@ fun ProductsList(navHostController: NavHostController, productsViewModel: Produc
fontWeight = FontWeight.Bold fontWeight = FontWeight.Bold
) )
} }
Button(
modifier = Modifier
.padding(top = 160.dp)
.size(340.dp, 60.dp),
colors = ButtonDefaults.buttonColors(
backgroundColor = MyOrange
),
border = BorderStroke(2.dp, color = MyLightYellow),
shape = RoundedCornerShape(20.dp),
onClick = {
navHostController.navigate(ScreenPaths.analysis.name)
}
) {
Text(
text = "Статистика",
fontFamily = NunitoFamily,
fontSize = 24.sp,
fontWeight = FontWeight.Bold
)
}
LazyColumn( LazyColumn(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.padding(top = 160.dp) modifier = Modifier.padding(top = 240.dp)
) )
{ {
items( items(

View File

@ -1,5 +1,5 @@
package com.example.shawarma.utils package com.example.shawarma.utils
enum class ScreenPaths { enum class ScreenPaths {
authorization, registration, home, discount, cart, orders, products, product authorization, registration, home, discount, cart, orders, products, product, analysis
} }

View File

@ -1,5 +1,6 @@
package com.example.shawarma.viewmodels package com.example.shawarma.viewmodels
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.paging.PagingData import androidx.paging.PagingData
@ -25,5 +26,13 @@ class ProductsViewModel @Inject constructor(
} }
} }
val topProductList = MutableLiveData<List<ProductModel>?>(null)
fun getTopProductsList(token: String, period: String) {
viewModelScope.launch {
topProductList.postValue(productRepository.getTopProducts(period, token))
}
}
} }