некорректное отображение данных в корзине

This commit is contained in:
dasha 2023-12-20 16:26:43 +04:00
parent a14249d6ef
commit a66218c7ab
19 changed files with 243262 additions and 168 deletions

View File

@ -90,6 +90,11 @@ interface MyServerService {
@Query("userId") userId: Int, @Query("userId") userId: Int,
): List<UserSessionWithSessionRemote> ): List<UserSessionWithSessionRemote>
@GET("userssessions")
suspend fun getUserSessions(
@Query("userId") userId: Int,
): List<UserSessionRemote>
@GET("userssessions?_expand=session") @GET("userssessions?_expand=session")
suspend fun getUsersSessions(): List<UserSessionWithSessionRemote> suspend fun getUsersSessions(): List<UserSessionWithSessionRemote>

View File

@ -48,13 +48,13 @@ class RestCinemaRepository(
override suspend fun getCinema(uid: Int): CinemaWithSessions { override suspend fun getCinema(uid: Int): CinemaWithSessions {
val cinemaWithSessions = service.getCinemaWithSessions(uid) val cinemaWithSessions = service.getCinemaWithSessions(uid)
val orders = service.getOrders()
val sessions = cinemaWithSessions.sessions.map { sessionFromCinemaRemote -> val sessions = cinemaWithSessions.sessions.map { sessionFromCinemaRemote ->
SessionFromCinema( SessionFromCinema(
sessionFromCinemaRemote.id, sessionFromCinemaRemote.id,
sessionFromCinemaRemote.dateTime, sessionFromCinemaRemote.dateTime,
sessionFromCinemaRemote.price, sessionFromCinemaRemote.price,
sessionFromCinemaRemote.maxCount - service.getOrders().flatMap sessionFromCinemaRemote.maxCount - orders.flatMap
{ order -> { order ->
order.sessions.filter { session -> order.sessions.filter { session ->
session.id == sessionFromCinemaRemote.id && session.id == sessionFromCinemaRemote.id &&

View File

@ -11,7 +11,7 @@ class RestOrderSessionRepository(
private val dbOrderSessionRepository: OfflineOrderSessionRepository private val dbOrderSessionRepository: OfflineOrderSessionRepository
) : OrderSessionRepository { ) : OrderSessionRepository {
override suspend fun insertOrderSession(orderSessionCrossRef: OrderSessionCrossRef) { override suspend fun insertOrderSession(orderSessionCrossRef: OrderSessionCrossRef) {
var orderRemote = service.getOrder(orderSessionCrossRef.orderId) val orderRemote = service.getOrder(orderSessionCrossRef.orderId)
val session = service.getSession(orderSessionCrossRef.sessionId) val session = service.getSession(orderSessionCrossRef.sessionId)
val sessionFromOrder = SessionFromOrderRemote( val sessionFromOrder = SessionFromOrderRemote(
@ -23,10 +23,9 @@ class RestOrderSessionRepository(
session.cinema session.cinema
) )
val updatedSessions = orderRemote.sessions.toMutableList() orderRemote.sessions = orderRemote.sessions.toMutableList().apply {
updatedSessions.add(sessionFromOrder) add(sessionFromOrder)
}
orderRemote = orderRemote.copy(sessions = updatedSessions)
service.updateOrder(orderSessionCrossRef.orderId, orderRemote) service.updateOrder(orderSessionCrossRef.orderId, orderRemote)
dbOrderSessionRepository.insertOrderSession(orderSessionCrossRef) dbOrderSessionRepository.insertOrderSession(orderSessionCrossRef)
} }

View File

@ -37,12 +37,13 @@ class RestUserRepository(
) )
) )
} }
val orders = service.getOrders()
val sessions = cart.map { sessionFromCartRemote -> val sessions = cart.map { sessionFromCartRemote ->
SessionFromCart( SessionFromCart(
uid = sessionFromCartRemote.sessionId, uid = sessionFromCartRemote.sessionId,
dateTime = sessionFromCartRemote.session.dateTime, dateTime = sessionFromCartRemote.session.dateTime,
price = sessionFromCartRemote.session.price, price = sessionFromCartRemote.session.price,
availableCount = sessionFromCartRemote.session.maxCount - service.getOrders() availableCount = sessionFromCartRemote.session.maxCount - orders
.flatMap .flatMap
{ order -> { order ->
order.sessions.filter { session -> order.sessions.filter { session ->

View File

@ -46,16 +46,20 @@ class RestUserSessionRepository(
val userSessionRemote = service.getUserSession( val userSessionRemote = service.getUserSession(
userSessionCrossRef.userId, userSessionCrossRef.userId,
userSessionCrossRef.sessionId userSessionCrossRef.sessionId
).first() ).firstOrNull() ?: return
service.deleteUserSession(userSessionRemote.id) service.deleteUserSession(userSessionRemote.id)
dbUserSessionRepository.deleteUserSession(userSessionCrossRef) dbUserSessionRepository.deleteUserSession(userSessionCrossRef)
} }
override suspend fun deleteUserSessions(userId: Int) { override suspend fun deleteUserSessions(userId: Int) {
val cart = service.getUserCart(userId) val cart = service.getUserSessions(userId)
cart.forEach { cart.forEach {
service.deleteUserSession(it.id) service.deleteUserSession(it.id)
} }
dbUserSessionRepository.deleteUserSessions(userId) dbUserSessionRepository.deleteUserSessions(userId)
} }
override suspend fun deleteUserSessions(userSessionCrossRefs: List<UserSessionCrossRef>) {
userSessionCrossRefs.forEach { deleteUserSession(it) }
}
} }

View File

@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
@ -16,6 +17,7 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
@ -33,8 +35,11 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import com.example.myapplication.LiveStore import com.example.myapplication.LiveStore
import com.example.myapplication.R import com.example.myapplication.R
import com.example.myapplication.api.ApiStatus
import com.example.myapplication.composeui.navigation.Screen
import com.example.myapplication.database.entities.composeui.AppViewModelProvider import com.example.myapplication.database.entities.composeui.AppViewModelProvider
import com.example.myapplication.database.entities.model.Session import com.example.myapplication.database.entities.model.Session
import com.example.myapplication.database.entities.model.SessionFromCart import com.example.myapplication.database.entities.model.SessionFromCart
@ -44,6 +49,7 @@ import org.threeten.bp.format.DateTimeFormatter
@Composable @Composable
fun Cart( fun Cart(
navController: NavController,
viewModel: CartViewModel = viewModel(factory = AppViewModelProvider.Factory) viewModel: CartViewModel = viewModel(factory = AppViewModelProvider.Factory)
) { ) {
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
@ -52,29 +58,52 @@ fun Cart(
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
viewModel.refreshState() viewModel.refreshState()
} }
Cart( when (viewModel.apiStatus) {
cartUiState = cartUiState, ApiStatus.DONE -> {
modifier = Modifier Cart(
.padding(all = 10.dp), cartUiState = cartUiState,
onChangeCount = { session: SessionFromCart, count: Int -> modifier = Modifier
coroutineScope.launch { .padding(all = 10.dp),
viewModel.updateFromCart( onChangeCount = { session: SessionFromCart, count: Int ->
session = Session( coroutineScope.launch {
uid = session.uid, viewModel.updateFromCart(
dateTime = session.dateTime, session = Session(
price = session.price, uid = session.uid,
maxCount = 0, dateTime = session.dateTime,
cinemaId = session.cinemaId price = session.price,
), count = count, availableCount = session.availableCount maxCount = 0,
) cinemaId = session.cinemaId
} ), count = count, availableCount = session.availableCount
}, )
onAddToOrder = { sessions: List<SessionFromCart> -> }
coroutineScope.launch { },
viewModel.addToOrder(sessions = sessions) onAddToOrder = { sessions: List<SessionFromCart> ->
} coroutineScope.launch {
viewModel.addToOrder(sessions = sessions)
}
},
onDelete = { session: SessionFromCart ->
coroutineScope.launch {
viewModel.removeFromCart(
session = Session(
uid = session.uid,
dateTime = session.dateTime,
price = session.price,
maxCount = 0,
cinemaId = session.cinemaId
)
)
}
}
)
} }
)
ApiStatus.LOADING -> LoadingPlaceholder()
else -> ErrorPlaceholder(
message = viewModel.apiError,
onBack = { navController.navigate(Screen.Report.route) }
)
}
} }
@Composable @Composable
@ -82,7 +111,8 @@ private fun Cart(
cartUiState: CartUiState, cartUiState: CartUiState,
modifier: Modifier, modifier: Modifier,
onChangeCount: (SessionFromCart, Int) -> Unit, onChangeCount: (SessionFromCart, Int) -> Unit,
onAddToOrder: (List<SessionFromCart>) -> Unit onAddToOrder: (List<SessionFromCart>) -> Unit,
onDelete: (SessionFromCart) -> Unit
) { ) {
LazyColumn( LazyColumn(
modifier = modifier modifier = modifier
@ -95,9 +125,13 @@ private fun Cart(
.padding(10.dp) .padding(10.dp)
.clip(RoundedCornerShape(16.dp)) .clip(RoundedCornerShape(16.dp))
.background(MaterialTheme.colorScheme.secondary), .background(MaterialTheme.colorScheme.secondary),
onChangeCount = onChangeCount onChangeCount = onChangeCount,
onDelete = onDelete,
) )
} }
item {
Spacer(modifier = Modifier.height(48.dp))
}
} }
val user = LiveStore.user.observeAsState() val user = LiveStore.user.observeAsState()
if (user.value?.role == UserRole.USER) { if (user.value?.role == UserRole.USER) {
@ -107,7 +141,7 @@ private fun Cart(
Button( Button(
onClick = { onAddToOrder(cartUiState.sessionList) }, onClick = { onAddToOrder(cartUiState.sessionList) },
modifier = Modifier modifier = Modifier
.padding(16.dp) .padding(6.dp)
.fillMaxWidth() .fillMaxWidth()
) { Text("Купить") } ) { Text("Купить") }
} }
@ -119,25 +153,26 @@ private fun SessionListItem(
session: SessionFromCart, session: SessionFromCart,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
onChangeCount: (SessionFromCart, Int) -> Unit, onChangeCount: (SessionFromCart, Int) -> Unit,
onDelete: (SessionFromCart) -> Unit
) { ) {
val dateFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm") val dateFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm")
val formattedDate = dateFormatter.format(session.dateTime) val formattedDate = dateFormatter.format(session.dateTime)
Column { Text(
Text( text = formattedDate,
text = formattedDate, color = MaterialTheme.colorScheme.onBackground,
color = MaterialTheme.colorScheme.onBackground, )
) Column(modifier = modifier.fillMaxWidth()) {
Box( Box(
modifier = modifier modifier = Modifier
.fillMaxWidth()
.padding(8.dp)
) { ) {
Row( Row(
modifier = Modifier modifier = Modifier.fillMaxWidth(),
.fillMaxWidth()
.padding(8.dp),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween horizontalArrangement = Arrangement.SpaceBetween
) { ) {
if (session.cinema.image != null) if (session.cinema.image != null) {
Image( Image(
bitmap = BitmapFactory.decodeByteArray( bitmap = BitmapFactory.decodeByteArray(
session.cinema.image, session.cinema.image,
@ -149,6 +184,7 @@ private fun SessionListItem(
.size(90.dp) .size(90.dp)
.padding(4.dp) .padding(4.dp)
) )
}
Column( Column(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
@ -157,54 +193,65 @@ private fun SessionListItem(
Text( Text(
text = "${session.cinema.name}, ${session.cinema.year}\n" + text = "${session.cinema.name}, ${session.cinema.year}\n" +
"Цена: ${session.price}\n" + "Цена: ${session.price}\n" +
"${session.count}/${session.availableCount}", if (session.availableCount == 0) "Недоступно" else "${session.count}/${session.availableCount}",
color = MaterialTheme.colorScheme.onSecondary color = MaterialTheme.colorScheme.onSecondary
) )
} }
}
}
Box( Row(
modifier = Modifier modifier = Modifier
.background( .background(color = MaterialTheme.colorScheme.primary)
color = MaterialTheme.colorScheme.background, .fillMaxWidth(),
shape = RoundedCornerShape(10.dp) horizontalArrangement = Arrangement.spacedBy(8.dp),
) // Задаем фон для кнопок verticalAlignment = Alignment.CenterVertically
) {
IconButton(
onClick = { onDelete(session) }
) {
Icon(
imageVector = Icons.Default.Delete,
contentDescription = "Удалить",
tint = MaterialTheme.colorScheme.onPrimary
)
}
Spacer(modifier = Modifier.weight(1F))
if (session.availableCount != 0) {
IconButton(
enabled = session.count != 1,
onClick = { onChangeCount(session, session.count - 1) }
) { ) {
Row( Icon(
verticalAlignment = Alignment.CenterVertically imageVector = ImageVector.vectorResource(id = R.drawable.minus),
) { contentDescription = "Уменьшить",
IconButton( tint = MaterialTheme.colorScheme.onPrimary
onClick = { onChangeCount(session, session.count - 1) } )
) {
Icon(
imageVector = ImageVector.vectorResource(id = R.drawable.minus),
contentDescription = "Уменьшить",
tint = MaterialTheme.colorScheme.onBackground,
modifier = Modifier.size(10.dp)
)
}
Text(
text = "${session.count}",
color = MaterialTheme.colorScheme.onBackground
)
IconButton(
onClick = {
onChangeCount(
session,
if (session.count != session.availableCount) session.count + 1 else session.count
)
}
) {
Icon(
imageVector = Icons.Default.Add,
contentDescription = "Увеличить",
tint = MaterialTheme.colorScheme.onBackground,
modifier = Modifier.size(10.dp)
)
}
}
} }
Text(
text = "${session.count}",
color = MaterialTheme.colorScheme.onPrimary
)
IconButton(
enabled = session.count != session.availableCount,
onClick = {
onChangeCount(
session,
if (session.count != session.availableCount) session.count + 1 else session.count
)
}
) {
Icon(
imageVector = Icons.Default.Add,
contentDescription = "Увеличить",
tint = MaterialTheme.colorScheme.onPrimary
)
}
} }
} }
} }

View File

@ -3,6 +3,7 @@ package com.example.myapplication.composeui
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.room.Transaction
import com.example.myapplication.LiveStore import com.example.myapplication.LiveStore
import com.example.myapplication.database.entities.model.Order import com.example.myapplication.database.entities.model.Order
import com.example.myapplication.database.entities.model.OrderSessionCrossRef import com.example.myapplication.database.entities.model.OrderSessionCrossRef
@ -25,39 +26,45 @@ class CartViewModel(
var cartUiState by mutableStateOf(CartUiState()) var cartUiState by mutableStateOf(CartUiState())
private set private set
suspend fun refreshState() { suspend fun refreshState(needLoadingScreen: Boolean = true) {
val userId: Int = LiveStore.user.value?.uid ?: 0 val userId: Int = LiveStore.user.value?.uid ?: return
runInScope( runInScope(
actionSuccess = { actionSuccess = {
val cart = userRepository.getCartByUser(userId) cartUiState = CartUiState(userRepository.getCartByUser(userId))
cartUiState = CartUiState(cart)
}, actionError = { }, actionError = {
cartUiState = CartUiState() cartUiState = CartUiState()
} },
needLoadingScreen = needLoadingScreen
) )
} }
@Transaction
suspend fun addToOrder(sessions: List<SessionFromCart>) { suspend fun addToOrder(sessions: List<SessionFromCart>) {
if (isLoading) if (isLoading)
return return
isLoading = true isLoading = true
val userId: Int = LiveStore.user.value?.uid ?: return val userId: Int = LiveStore.user.value?.uid ?: return
if (sessions.isEmpty()) val cart = sessions.filter { it.availableCount != 0 }
if (cart.isEmpty())
return return
runInScope( runInScope(
actionSuccess = { actionSuccess = {
val orderId = orderRepository.insertOrder(Order(0, userId, LocalDateTime.now())) val orderId = orderRepository.insertOrder(Order(0, userId, LocalDateTime.now()))
sessions.forEach { session -> cart.forEach { session ->
orderSessionRepository.insertOrderSession( if (session.availableCount != 0) {
OrderSessionCrossRef( orderSessionRepository.insertOrderSession(
orderId.toInt(), OrderSessionCrossRef(
session.uid, orderId.toInt(),
session.price, session.uid,
session.count session.price,
session.count
)
) )
) }
} }
userSessionRepository.deleteUserSessions(userId) userSessionRepository.deleteUserSessions(cart.map {
UserSessionCrossRef(userId, it.uid, it.count)
})
refreshState() refreshState()
} }
) )
@ -97,7 +104,9 @@ class CartViewModel(
) )
) )
refreshState() refreshState()
} },
actionError = { },
needLoadingScreen = false
) )
} }
} }

View File

@ -1,6 +1,5 @@
package com.example.myapplication.composeui package com.example.myapplication.composeui
import android.content.res.Configuration
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
@ -8,8 +7,6 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
@ -17,12 +14,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.TextUnitType import androidx.compose.ui.unit.TextUnitType
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.example.myapplication.R import com.example.myapplication.R
import com.example.myapplication.ui.theme.PmudemoTheme
@Composable @Composable
@ -67,30 +62,4 @@ fun LoadingPlaceholder() {
text = stringResource(id = R.string.loading) text = stringResource(id = R.string.loading)
) )
} }
}
@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
fun ErrorPlaceholderPreview() {
PmudemoTheme {
Surface(
color = MaterialTheme.colorScheme.background
) {
ErrorPlaceholder("Error", onBack = {})
}
}
}
@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
fun LoadingPlaceholderPreview() {
PmudemoTheme {
Surface(
color = MaterialTheme.colorScheme.background
) {
LoadingPlaceholder()
}
}
} }

View File

@ -25,8 +25,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import com.example.myapplication.api.ApiStatus import com.example.myapplication.api.ApiStatus
import com.example.myapplication.api.session.ReportRemote import com.example.myapplication.api.session.ReportRemote
import com.example.myapplication.composeui.navigation.Screen
import com.example.myapplication.database.entities.composeui.AppViewModelProvider import com.example.myapplication.database.entities.composeui.AppViewModelProvider
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.threeten.bp.format.DateTimeFormatter import org.threeten.bp.format.DateTimeFormatter
@ -35,6 +37,7 @@ import java.util.Date
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun Report( fun Report(
navController: NavController,
viewModel: ReportViewModel = viewModel(factory = AppViewModelProvider.Factory) viewModel: ReportViewModel = viewModel(factory = AppViewModelProvider.Factory)
) { ) {
val dateStateStart = rememberDatePickerState(initialDisplayMode = DisplayMode.Input) val dateStateStart = rememberDatePickerState(initialDisplayMode = DisplayMode.Input)
@ -87,7 +90,6 @@ fun Report(
Button( Button(
onClick = { coroutineScope.launch { viewModel.getReport() } }, onClick = { coroutineScope.launch { viewModel.getReport() } },
enabled = viewModel.reportUiState.isEntryValid, enabled = viewModel.reportUiState.isEntryValid,
shape = MaterialTheme.shapes.small,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text(text = "Получить отчет") Text(text = "Получить отчет")
@ -100,7 +102,7 @@ fun Report(
ApiStatus.LOADING -> LoadingPlaceholder() ApiStatus.LOADING -> LoadingPlaceholder()
else -> ErrorPlaceholder( else -> ErrorPlaceholder(
message = viewModel.apiError, message = viewModel.apiError,
onBack = { } onBack = { navController.navigate(Screen.Report.route) }
) )
} }
} }

View File

@ -162,7 +162,7 @@ fun Navhost(
) { ) {
composable(Screen.CinemaList.route) { CinemaList(navController) } composable(Screen.CinemaList.route) { CinemaList(navController) }
composable(Screen.OrderList.route) { OrderList(navController) } composable(Screen.OrderList.route) { OrderList(navController) }
composable(Screen.Cart.route) { Cart() } composable(Screen.Cart.route) { Cart(navController) }
composable(Screen.UserProfile.route) { UserProfile(isDarkTheme, dataStore) } composable(Screen.UserProfile.route) { UserProfile(isDarkTheme, dataStore) }
composable( composable(
Screen.CinemaEdit.route, Screen.CinemaEdit.route,
@ -189,7 +189,7 @@ fun Navhost(
) { backStackEntry -> ) { backStackEntry ->
backStackEntry.arguments?.let { OrderView(navController) } backStackEntry.arguments?.let { OrderView(navController) }
} }
composable(Screen.Report.route) { Report() } composable(Screen.Report.route) { Report(navController) }
} }
} }

View File

@ -113,8 +113,7 @@ fun SessionList(
IconButton( IconButton(
onClick = { onClick = {
coroutineScope.launch { coroutineScope.launch {
if (session.availableCount != 0) viewModel.addSessionInCart(sessionId = session.uid)
viewModel.addSessionInCart(sessionId = session.uid)
} }
}, },
) { ) {

View File

@ -29,17 +29,13 @@ class SessionListViewModel(
suspend fun addSessionInCart(sessionId: Int, count: Int = 1) { suspend fun addSessionInCart(sessionId: Int, count: Int = 1) {
val userId: Int = LiveStore.user.value?.uid ?: return val userId: Int = LiveStore.user.value?.uid ?: return
runInScope(actionSuccess = { runInScope(actionSuccess = {
try { userSessionRepository.insertUserSession(
userSessionRepository.insertUserSession( UserSessionCrossRef(
UserSessionCrossRef( userId,
userId, sessionId,
sessionId, count
count
)
) )
} catch (_: Exception) { )
}
}) })
} }
} }

View File

@ -76,7 +76,7 @@ fun UserProfile(
}, },
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(8.dp) .padding(start = 2.dp, top = 10.dp)
) { Text("Выход") } ) { Text("Выход") }
} }
} else { } else {
@ -160,7 +160,7 @@ fun UserProfile(
onClick = { coroutine.launch { viewModel.signUp() } }, onClick = { coroutine.launch { viewModel.signUp() } },
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(8.dp) .padding(start = 2.dp, top = 8.dp)
) { ) {
Text("Регистрация") Text("Регистрация")
} }
@ -182,7 +182,7 @@ fun UserProfile(
}, },
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(8.dp) .padding(start = 2.dp, top = 8.dp)
) { ) {
Text("Вход") Text("Вход")
} }

View File

@ -111,7 +111,6 @@ private fun CinemaEdit(
Button( Button(
onClick = onClick, onClick = onClick,
enabled = cinemaUiState.isEntryValid, enabled = cinemaUiState.isEntryValid,
shape = MaterialTheme.shapes.small,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text(text = stringResource(R.string.Save_button)) Text(text = stringResource(R.string.Save_button))

View File

@ -9,7 +9,6 @@ import androidx.compose.material3.Button
import androidx.compose.material3.DatePicker import androidx.compose.material3.DatePicker
import androidx.compose.material3.DisplayMode import androidx.compose.material3.DisplayMode
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TimePicker import androidx.compose.material3.TimePicker
@ -153,7 +152,6 @@ private fun SessionEdit(
Button( Button(
onClick = onClick, onClick = onClick,
enabled = sessionUiState.isEntryValid, enabled = sessionUiState.isEntryValid,
shape = MaterialTheme.shapes.small,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Text(text = stringResource(R.string.Save_button)) Text(text = stringResource(R.string.Save_button))

View File

@ -17,7 +17,7 @@ interface UserSessionCrossRefDao {
suspend fun update(userSessionCrossRef: UserSessionCrossRef) suspend fun update(userSessionCrossRef: UserSessionCrossRef)
@Delete @Delete
suspend fun delete(userSessionCrossRef: UserSessionCrossRef) suspend fun delete(vararg userSessionCrossRef: UserSessionCrossRef)
@Query("DELETE FROM users_sessions where users_sessions.user_id = :userId") @Query("DELETE FROM users_sessions where users_sessions.user_id = :userId")
suspend fun deleteByUserUid(userId: Int) suspend fun deleteByUserUid(userId: Int)

View File

@ -16,5 +16,8 @@ class OfflineUserSessionRepository(private val userSessionDao: UserSessionCrossR
override suspend fun deleteUserSessions(userId: Int) = userSessionDao.deleteByUserUid(userId) override suspend fun deleteUserSessions(userId: Int) = userSessionDao.deleteByUserUid(userId)
override suspend fun deleteUserSessions(userSessionCrossRefs: List<UserSessionCrossRef>) =
userSessionDao.delete(*userSessionCrossRefs.toTypedArray())
suspend fun deleteSessionsByUid(sessionId: Int) = userSessionDao.deleteBySessionUid(sessionId) suspend fun deleteSessionsByUid(sessionId: Int) = userSessionDao.deleteBySessionUid(sessionId)
} }

View File

@ -7,4 +7,5 @@ interface UserSessionRepository {
suspend fun updateUserSession(userSessionCrossRef: UserSessionCrossRef) suspend fun updateUserSession(userSessionCrossRef: UserSessionCrossRef)
suspend fun deleteUserSession(userSessionCrossRef: UserSessionCrossRef) suspend fun deleteUserSession(userSessionCrossRef: UserSessionCrossRef)
suspend fun deleteUserSessions(userId: Int) suspend fun deleteUserSessions(userId: Int)
suspend fun deleteUserSessions(userSessionCrossRefs: List<UserSessionCrossRef>)
} }

File diff suppressed because it is too large Load Diff