From 60fce778edd72b9c244eec2d183754488634800c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A2=D0=B0=D1=82=D1=8C=D1=8F=D0=BD=D0=B0=20=D0=90=D1=80?= =?UTF-8?q?=D1=82=D0=B0=D0=BC=D0=BE=D0=BD=D0=BE=D0=B2=D0=B0?= Date: Wed, 27 Dec 2023 03:18:53 +0400 Subject: [PATCH] =?UTF-8?q?=D0=BE=D0=B8=20=D0=B1=D1=80=D0=BE=D0=BD=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=BD=D0=BE=D1=80?= =?UTF-8?q?=D0=BC=20=D1=83=D0=B4=D0=B0=D0=BB=D1=8F=D1=8E=D1=82=D1=81=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/OfflineTicketRepository.kt | 3 +- .../graphs/HomeNavGraph.kt | 13 +- .../navigation/BottomBarScreen.kt | 9 + .../is/airticketrentservice/screen/MyRents.kt | 163 ++++++++++------ .../is/airticketrentservice/screen/Profile.kt | 4 +- .../airticketrentservice/screen/RentEdit.kt | 183 ++---------------- .../airticketrentservice/screen/RentList.kt | 18 +- .../airticketrentservice/screen/UserList.kt | 77 +------- .../viewModel/UsersRentsViewModel.kt | 17 +- server/data.json | 40 ++-- server/data.json.bak | 61 +++--- 11 files changed, 202 insertions(+), 386 deletions(-) diff --git a/app/src/main/java/ru/ulstu/is/airticketrentservice/database/repository/OfflineTicketRepository.kt b/app/src/main/java/ru/ulstu/is/airticketrentservice/database/repository/OfflineTicketRepository.kt index 9edc2e4..3999a47 100644 --- a/app/src/main/java/ru/ulstu/is/airticketrentservice/database/repository/OfflineTicketRepository.kt +++ b/app/src/main/java/ru/ulstu/is/airticketrentservice/database/repository/OfflineTicketRepository.kt @@ -7,7 +7,6 @@ import androidx.paging.PagingSource import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.first import ru.ulstu.`is`.airticketrentservice.database.dao.TicketDao -import ru.ulstu.`is`.airticketrentservice.database.models.Flight import ru.ulstu.`is`.airticketrentservice.database.models.Ticket class OfflineTicketRepository(private val ticketDao: TicketDao) : TicketRepository { @@ -27,5 +26,5 @@ class OfflineTicketRepository(private val ticketDao: TicketDao) : TicketReposito override suspend fun getFlightsTickets(flightId: Int): List = ticketDao.getFlightsTickets(flightId) suspend fun clearTickets() = ticketDao.deleteAll() suspend fun insertTickets(tickets: List) = - ticketDao.insert(*tickets.toTypedArray())[0] + ticketDao.insert(*tickets.toTypedArray()) } \ No newline at end of file diff --git a/app/src/main/java/ru/ulstu/is/airticketrentservice/graphs/HomeNavGraph.kt b/app/src/main/java/ru/ulstu/is/airticketrentservice/graphs/HomeNavGraph.kt index e19a4b8..f4241ff 100644 --- a/app/src/main/java/ru/ulstu/is/airticketrentservice/graphs/HomeNavGraph.kt +++ b/app/src/main/java/ru/ulstu/is/airticketrentservice/graphs/HomeNavGraph.kt @@ -18,6 +18,7 @@ import ru.ulstu.`is`.airticketrentservice.screen.MyRents import ru.ulstu.`is`.airticketrentservice.screen.Profile import ru.ulstu.`is`.airticketrentservice.screen.RentEdit import ru.ulstu.`is`.airticketrentservice.screen.RentList +import ru.ulstu.`is`.airticketrentservice.screen.RentStatusEdit import ru.ulstu.`is`.airticketrentservice.screen.TicketEdit import ru.ulstu.`is`.airticketrentservice.screen.TicketList import ru.ulstu.`is`.airticketrentservice.screen.TicketView @@ -109,7 +110,17 @@ fun HomeNavGraph( } ) ){ - RentEdit(navController) + RentEdit() + } + composable( + route = BottomBarScreen.RentStatusEdit.route, + arguments = listOf( + navArgument("id") { + type = NavType.IntType + } + ) + ){ + RentStatusEdit(navController) } composable( route = BottomBarScreen.FlightEdit.route, diff --git a/app/src/main/java/ru/ulstu/is/airticketrentservice/navigation/BottomBarScreen.kt b/app/src/main/java/ru/ulstu/is/airticketrentservice/navigation/BottomBarScreen.kt index 903b1be..d440e9c 100644 --- a/app/src/main/java/ru/ulstu/is/airticketrentservice/navigation/BottomBarScreen.kt +++ b/app/src/main/java/ru/ulstu/is/airticketrentservice/navigation/BottomBarScreen.kt @@ -112,6 +112,15 @@ sealed class BottomBarScreen( return "rent-edit/$id" } } + object RentStatusEdit: BottomBarScreen( + route = "rent-status-edit/{id}", + title ="", + icon = Icons.Filled.AccountCircle + ) { + fun passId(id: String): String{ + return "rent-status-edit/$id" + } + } object TicketEdit: BottomBarScreen( route = "ticket-edit/{id}", title ="", diff --git a/app/src/main/java/ru/ulstu/is/airticketrentservice/screen/MyRents.kt b/app/src/main/java/ru/ulstu/is/airticketrentservice/screen/MyRents.kt index 1984af8..bf7c028 100644 --- a/app/src/main/java/ru/ulstu/is/airticketrentservice/screen/MyRents.kt +++ b/app/src/main/java/ru/ulstu/is/airticketrentservice/screen/MyRents.kt @@ -1,38 +1,28 @@ package ru.ulstu.`is`.airticketrentservice.screen +import android.annotation.SuppressLint import android.util.Log -import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.animateColorAsState import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.animation.core.spring -import androidx.compose.animation.fadeOut 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.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Add -import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.outlined.Delete -import androidx.compose.material.pullrefresh.PullRefreshIndicator -import androidx.compose.material.pullrefresh.pullRefresh -import androidx.compose.material.pullrefresh.rememberPullRefreshState import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.DismissDirection import androidx.compose.material3.DismissState import androidx.compose.material3.DismissValue +import androidx.compose.material3.DismissValue.DismissedToStart import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold @@ -40,38 +30,29 @@ import androidx.compose.material3.SwipeToDismiss import androidx.compose.material3.Text import androidx.compose.material3.rememberDismissState import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.SideEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment -import androidx.compose.ui.Alignment.Companion.CenterHorizontally import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.scale import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource +import androidx.compose.ui.res.colorResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import androidx.compose.ui.zIndex import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController -import androidx.paging.PagingData -import androidx.paging.compose.LazyPagingItems -import androidx.paging.compose.collectAsLazyPagingItems -import androidx.paging.compose.itemContentType -import androidx.paging.compose.itemKey -import kotlinx.coroutines.delay import kotlinx.coroutines.launch import ru.ulstu.`is`.airticketrentservice.database.models.Rent import ru.ulstu.`is`.airticketrentservice.viewModel.AppViewModelProvider import ru.ulstu.`is`.airticketrentservice.viewModel.CurrentUserViewModel -import ru.ulstu.`is`.airticketrentservice.viewModel.RentListViewModel import ru.ulstu.`is`.airticketrentservice.R -import ru.ulstu.`is`.airticketrentservice.database.models.Flight import ru.ulstu.`is`.airticketrentservice.navigation.BottomBarScreen import ru.ulstu.`is`.airticketrentservice.viewModel.UsersRentsViewModel @@ -82,9 +63,11 @@ fun MyRents( currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory) ) { val coroutineScope = rememberCoroutineScope() + var userRentsUiState by remember { mutableStateOf(viewModel.userRentsUiState) } - val getUser by remember { mutableStateOf(currentUserViewModel.user) } - val userRentsUiState = viewModel.userRentsUiState + SideEffect { + userRentsUiState = viewModel.userRentsUiState + } Log.d("RentListViewModel", "мои бронирования: ${userRentsUiState.rentList}") Scaffold( @@ -101,67 +84,118 @@ fun MyRents( onSwipe = { rent: Rent -> coroutineScope.launch { viewModel.deleteRent(rent) + viewModel.refreshRents() } } ) } } -@OptIn(ExperimentalMaterial3Api::class) -@Composable -private fun DismissBackground(dismissState: DismissState) { - val color = when (dismissState.dismissDirection) { - DismissDirection.StartToEnd -> Color.Transparent - DismissDirection.EndToStart -> Color(0xFFFF1744) - null -> Color.Transparent - } - val direction = dismissState.dismissDirection - - Row( - modifier = Modifier - .fillMaxSize() - .background(color) - .padding(12.dp, 8.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.End - ) { - if (direction == DismissDirection.EndToStart) { - Icon( - Icons.Default.Delete, - contentDescription = "delete", - tint = Color.White - ) - } - } -} - @OptIn(ExperimentalMaterial3Api::class) @Composable private fun SwipeToDelete( dismissState: DismissState, + rentList: MutableList, rent: Rent, onClick: (id: Int) -> Unit ) { + LaunchedEffect(dismissState.targetValue) { + if (dismissState.targetValue == DismissedToStart) { + rentList.remove(rent) + } + } SwipeToDismiss( - modifier = Modifier.zIndex(1f), state = dismissState, - directions = setOf( - DismissDirection.EndToStart - ), + directions = setOf(DismissDirection.EndToStart), background = { - DismissBackground(dismissState) + val backgroundColor by animateColorAsState( + when (dismissState.targetValue) { + DismissedToStart -> Color.Red.copy(alpha = 0.8f) + else -> Color.White + }, label = "" + ) + val iconScale by animateFloatAsState( + targetValue = if (dismissState.targetValue == DismissedToStart) 1.3f else 0.5f, + label = "" + ) + Box( + Modifier + .fillMaxSize() + .background(color = backgroundColor) + .padding(end = 16.dp), + contentAlignment = Alignment.CenterEnd + ) { + Icon( + modifier = Modifier.scale(iconScale), + imageVector = Icons.Outlined.Delete, + contentDescription = "Delete", + tint = Color.White + ) + } }, dismissContent = { - RentListItem(rent = rent, + RentListItem( + rent = rent, modifier = Modifier .padding(vertical = 7.dp) .clip(shape = RoundedCornerShape(15.dp)) - .clickable { onClick(rent.id) }) + .clickable { onClick(rent.id) } + ) } ) } -@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class) + +//@OptIn(ExperimentalMaterial3Api::class) +//@Composable +//private fun SwipeToDelete( +// dismissState: DismissState, +// rent: Rent, +// onClick: (id: Int) -> Unit +//) { +// SwipeToDismiss( +// state = dismissState, +// directions = setOf( +// DismissDirection.EndToStart +// ), +// background = { +// val backgroundColor by animateColorAsState( +// when (dismissState.targetValue) { +// DismissedToStart -> Color.Red.copy(alpha = 0.8f) +// else -> Color.White +// }, label = "" +// ) +// val iconScale by animateFloatAsState( +// targetValue = if (dismissState.targetValue == DismissedToStart) 1.3f else 0.5f, +// label = "" +// ) +// Box( +// Modifier +// .fillMaxSize() +// .background(color = backgroundColor) +// .padding(end = 16.dp), +// contentAlignment = Alignment.CenterEnd +// ) { +// Icon( +// modifier = Modifier.scale(iconScale), +// imageVector = Icons.Outlined.Delete, +// contentDescription = "Delete", +// tint = Color.White +// ) +// } +// }, +// dismissContent = { +// RentListItem(rent = rent, +// modifier = Modifier +// .padding(vertical = 7.dp) +// .clip(shape = RoundedCornerShape(15.dp)) +// .clickable { onClick(rent.id) }) +// } +// ) +//} + +@SuppressLint("MutableCollectionMutableState") +@OptIn(ExperimentalMaterial3Api::class) @Composable private fun MyRents( modifier: Modifier = Modifier, @@ -191,6 +225,7 @@ private fun MyRents( SwipeToDelete( dismissState = dismissState, + rentList = rentList.toMutableList(), rent = rent, onClick = onClick ) @@ -200,13 +235,15 @@ private fun MyRents( } } + @Composable private fun RentListItem( modifier: Modifier = Modifier, rent: Rent ) { Card( modifier = modifier.fillMaxWidth(), - elevation = CardDefaults.cardElevation(defaultElevation = 2.dp) + elevation = CardDefaults.cardElevation(defaultElevation = 2.dp), + colors = CardDefaults.cardColors(colorResource(id = R.color.lightlightBlue)) ) { Column( modifier = modifier.padding(all = 10.dp) diff --git a/app/src/main/java/ru/ulstu/is/airticketrentservice/screen/Profile.kt b/app/src/main/java/ru/ulstu/is/airticketrentservice/screen/Profile.kt index 0b62794..f49da22 100644 --- a/app/src/main/java/ru/ulstu/is/airticketrentservice/screen/Profile.kt +++ b/app/src/main/java/ru/ulstu/is/airticketrentservice/screen/Profile.kt @@ -170,7 +170,7 @@ fun Profile( Button( modifier = Modifier .fillMaxWidth() - .padding(5.dp), + .padding(top = 5.dp, bottom = 50.dp), onClick = { navController.navigate(AuthScreen.Login.route) }, @@ -179,7 +179,7 @@ fun Profile( pressedElevation = 6.dp ), shape = RoundedCornerShape(15.dp), - colors = ButtonDefaults.buttonColors(containerColor = colorResource(R.color.lightBlue)), + colors = ButtonDefaults.buttonColors(containerColor = Color.Red), content = { Text("Выйти") } diff --git a/app/src/main/java/ru/ulstu/is/airticketrentservice/screen/RentEdit.kt b/app/src/main/java/ru/ulstu/is/airticketrentservice/screen/RentEdit.kt index 48576e0..6d6f5eb 100644 --- a/app/src/main/java/ru/ulstu/is/airticketrentservice/screen/RentEdit.kt +++ b/app/src/main/java/ru/ulstu/is/airticketrentservice/screen/RentEdit.kt @@ -51,93 +51,27 @@ import ru.ulstu.`is`.airticketrentservice.viewModel.UsersListUiState @SuppressLint("UnrememberedMutableState") @Composable fun RentEdit( - navController: NavController, viewModel: RentEditViewModel = viewModel(factory = AppViewModelProvider.Factory), - userViewModel: UserEditViewModel = viewModel(factory = AppViewModelProvider.Factory), ticketViewModel: TicketEditViewModel = viewModel(factory = AppViewModelProvider.Factory) ) { - val coroutineScope = rememberCoroutineScope() - userViewModel.setCurrentUser(viewModel.rentUiState.rentDetails.userId) ticketViewModel.setCurrentTicket(viewModel.rentUiState.rentDetails.ticketId) RentEdit( rentUiState = viewModel.rentUiState, - userUiState = userViewModel.userUiState, - ticketUiState = ticketViewModel.ticketUiState, - onClick = { - coroutineScope.launch { - viewModel.saveRent() - navController.popBackStack() - } - }, - onUpdate = viewModel::updateUiState + ticketUiState = ticketViewModel.ticketUiState ) } -@OptIn(ExperimentalMaterial3Api::class) @Composable private fun RentEdit( rentUiState: RentUiState, - userUiState: UserUiState, - ticketUiState: TicketUiState, - onClick: () -> Unit, - onUpdate: (RentDetails) -> Unit + ticketUiState: TicketUiState ) { Column( Modifier .fillMaxWidth() .padding(all = 10.dp) ) { - TextField( - value = rentUiState.rentDetails.userId.toString(), - onValueChange = { onUpdate(rentUiState.rentDetails.copy(userId = it.toInt())) }, - modifier = Modifier.fillMaxWidth().padding(all = 5.dp), - colors = TextFieldDefaults.colors( - focusedContainerColor = Color.LightGray.copy(.2f), - unfocusedContainerColor = Color.LightGray.copy(.2f), - disabledContainerColor = Color.LightGray.copy(.2f), - focusedIndicatorColor = Color.Transparent, - unfocusedIndicatorColor = Color.Transparent, - ), - shape = RoundedCornerShape(15.dp), - label = { - Text("Номер пользователя") - } - ) - TextField( - value = rentUiState.rentDetails.ticketId.toString(), - onValueChange = { onUpdate(rentUiState.rentDetails.copy(ticketId = it.toInt())) }, - modifier = Modifier.fillMaxWidth().padding(all = 5.dp), - colors = TextFieldDefaults.colors( - focusedContainerColor = Color.LightGray.copy(.2f), - unfocusedContainerColor = Color.LightGray.copy(.2f), - disabledContainerColor = Color.LightGray.copy(.2f), - focusedIndicatorColor = Color.Transparent, - unfocusedIndicatorColor = Color.Transparent, - ), - shape = RoundedCornerShape(15.dp), - label = { - Text("Номер билета") - } - ) - TextField( - value = "${userUiState.userDetails.surname} ${userUiState.userDetails.name} ${userUiState.userDetails.patronymic}", - onValueChange = {}, - readOnly = true, - modifier = Modifier.fillMaxWidth().padding(all = 5.dp), - colors = TextFieldDefaults.colors( - focusedContainerColor = Color.LightGray.copy(.2f), - unfocusedContainerColor = Color.LightGray.copy(.2f), - disabledContainerColor = Color.LightGray.copy(.2f), - focusedIndicatorColor = Color.Transparent, - unfocusedIndicatorColor = Color.Transparent, - ), - shape = RoundedCornerShape(15.dp), - label = { - Text("Пользователь") - } - ) - TextField( value = "${ticketUiState.ticketDetails.ticket_cost}", onValueChange = {}, @@ -155,7 +89,6 @@ private fun RentEdit( Text("Стоимость билета") } ) - TextField( value = "${ticketUiState.ticketDetails.passengers_count}", onValueChange = {}, @@ -173,108 +106,22 @@ private fun RentEdit( Text("Количество пассажиров") } ) -// -// TextField( -// value = "Ожидает подтверждения", -// onValueChange = { onUpdate(rentUiState.rentDetails.copy(status = it)) }, -// readOnly = true, -// modifier = Modifier.fillMaxWidth(), -// colors = TextFieldDefaults.colors( -// focusedContainerColor = Color.LightGray.copy(.2f), -// unfocusedContainerColor = Color.LightGray.copy(.2f), -// disabledContainerColor = Color.LightGray.copy(.2f), -// focusedIndicatorColor = Color.Transparent, -// unfocusedIndicatorColor = Color.Transparent, -// ), -// shape = RoundedCornerShape(15.dp), -// label = { -// Text(stringResource(id = R.string.rent_status)) -// } -// ) - - var expanded by remember { mutableStateOf(false) } - - Box( - modifier = Modifier.fillMaxWidth().padding(all = 5.dp).clip(RoundedCornerShape(15.dp)) - ) { - ExposedDropdownMenuBox( - modifier = Modifier.fillMaxWidth(), - expanded = expanded, - onExpandedChange = { expanded = !expanded }, - ) - { - TextField( - value = rentUiState.rentDetails.status, - onValueChange = {}, - readOnly = true, - trailingIcon = { - TrailingIcon(expanded = expanded) - }, - modifier = Modifier.menuAnchor().fillMaxWidth(), - colors = TextFieldDefaults.colors( - focusedContainerColor = Color.LightGray.copy(.2f), - unfocusedContainerColor = Color.LightGray.copy(.2f), - disabledContainerColor = Color.LightGray.copy(.2f), - focusedIndicatorColor = Color.Transparent, - unfocusedIndicatorColor = Color.Transparent, - ), - shape = RoundedCornerShape(15.dp), - label = { - Text(stringResource(id = R.string.rent_status)) - } - ) - ExposedDropdownMenu( - expanded = expanded, - onDismissRequest = { expanded = false }, - modifier = Modifier - .background(Color.LightGray.copy(.2f)) - .exposedDropdownSize() - .fillMaxWidth() - ) { - DropdownMenuItem( - modifier = Modifier.fillMaxWidth().clip(RoundedCornerShape(15.dp)), - text = { Text("Подтверждено") }, - onClick = { - onUpdate(rentUiState.rentDetails.copy(status = "Подтверждено")) - expanded = false - } - ) - DropdownMenuItem( - modifier = Modifier.fillMaxWidth().clip(RoundedCornerShape(15.dp)), - text = { Text("Ожидает подтверждения") }, - onClick = { - onUpdate(rentUiState.rentDetails.copy(status = "Ожидает подтверждения")) - expanded = false - } - ) - DropdownMenuItem( - modifier = Modifier.fillMaxWidth().clip(RoundedCornerShape(15.dp)), - text = { Text("Отклонено") }, - onClick = { - onUpdate(rentUiState.rentDetails.copy(status = "Отклонено")) - expanded = false - } - ) - } - } - } - - Button( - enabled = rentUiState.isEntryValid, - modifier = Modifier - .fillMaxWidth() - .padding(all = 10.dp), - onClick = onClick, - elevation = ButtonDefaults.buttonElevation( - defaultElevation = 10.dp, - pressedElevation = 6.dp + TextField( + value = rentUiState.rentDetails.status, + onValueChange = {}, + readOnly = true, + modifier = Modifier.fillMaxWidth().padding(all = 5.dp), + colors = TextFieldDefaults.colors( + focusedContainerColor = Color.LightGray.copy(.2f), + unfocusedContainerColor = Color.LightGray.copy(.2f), + disabledContainerColor = Color.LightGray.copy(.2f), + focusedIndicatorColor = Color.Transparent, + unfocusedIndicatorColor = Color.Transparent, ), shape = RoundedCornerShape(15.dp), - colors = ButtonDefaults.buttonColors(containerColor = colorResource(R.color.lightBlue)), - content = { - Text(text = stringResource(R.string.rent_save_button)) + label = { + Text(stringResource(id = R.string.rent_status)) } ) - } } \ No newline at end of file diff --git a/app/src/main/java/ru/ulstu/is/airticketrentservice/screen/RentList.kt b/app/src/main/java/ru/ulstu/is/airticketrentservice/screen/RentList.kt index 73989cf..13d5dea 100644 --- a/app/src/main/java/ru/ulstu/is/airticketrentservice/screen/RentList.kt +++ b/app/src/main/java/ru/ulstu/is/airticketrentservice/screen/RentList.kt @@ -50,6 +50,7 @@ import androidx.compose.ui.Alignment.Companion.CenterHorizontally import androidx.compose.ui.Modifier import androidx.compose.ui.draw.scale import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview @@ -65,6 +66,7 @@ import androidx.paging.compose.itemKey import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.launch +import ru.ulstu.`is`.airticketrentservice.R import ru.ulstu.`is`.airticketrentservice.database.models.Rent import ru.ulstu.`is`.airticketrentservice.navigation.BottomBarScreen import ru.ulstu.`is`.airticketrentservice.viewModel.AppViewModelProvider @@ -85,17 +87,6 @@ fun RentList( val rentListUiState = viewModel.rentListUiState.collectAsLazyPagingItems() Scaffold( - topBar = {}, - floatingActionButton = { - FloatingActionButton( - onClick = { - val route = BottomBarScreen.RentEdit.passId(0.toString()) - navController.navigate(route) - }, - ) { - Icon(Icons.Filled.Add, "Добавить") - } - } ) { innerPadding -> RentList( modifier = Modifier @@ -103,7 +94,7 @@ fun RentList( .fillMaxSize(), rentList = rentListUiState, onClick = { uid: Int -> - val route = BottomBarScreen.RentEdit.passId(uid.toString()) + val route = BottomBarScreen.RentStatusEdit.passId(uid.toString()) navController.navigate(route) }, onSwipe = { rent: Rent -> @@ -246,7 +237,8 @@ private fun RentListItem( ) { Card( modifier = modifier.fillMaxWidth(), - elevation = CardDefaults.cardElevation(defaultElevation = 2.dp) + elevation = CardDefaults.cardElevation(defaultElevation = 2.dp), + colors = CardDefaults.cardColors(colorResource(id = R.color.lightlightBlue)) ) { Column( modifier = modifier.padding(all = 10.dp) diff --git a/app/src/main/java/ru/ulstu/is/airticketrentservice/screen/UserList.kt b/app/src/main/java/ru/ulstu/is/airticketrentservice/screen/UserList.kt index 2a4707d..0903583 100644 --- a/app/src/main/java/ru/ulstu/is/airticketrentservice/screen/UserList.kt +++ b/app/src/main/java/ru/ulstu/is/airticketrentservice/screen/UserList.kt @@ -1,15 +1,8 @@ package ru.ulstu.`is`.airticketrentservice.screen -import android.content.res.Configuration -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.animateColorAsState -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.animation.core.spring -import androidx.compose.animation.fadeOut 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.fillMaxSize @@ -19,53 +12,31 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Delete -import androidx.compose.material.icons.outlined.Delete -import androidx.compose.material.pullrefresh.PullRefreshIndicator -import androidx.compose.material.pullrefresh.pullRefresh -import androidx.compose.material.pullrefresh.rememberPullRefreshState import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.DismissDirection import androidx.compose.material3.DismissState -import androidx.compose.material3.DismissValue import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold -import androidx.compose.material3.Surface import androidx.compose.material3.SwipeToDismiss import androidx.compose.material3.Text import androidx.compose.material3.rememberDismissState import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment -import androidx.compose.ui.Alignment.Companion.CenterHorizontally import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.scale import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource +import androidx.compose.ui.res.colorResource import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController -import androidx.paging.PagingData -import androidx.paging.compose.LazyPagingItems -import androidx.paging.compose.collectAsLazyPagingItems -import androidx.paging.compose.itemContentType -import androidx.paging.compose.itemKey -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.launch +import ru.ulstu.`is`.airticketrentservice.R import ru.ulstu.`is`.airticketrentservice.database.models.User import ru.ulstu.`is`.airticketrentservice.navigation.BottomBarScreen import ru.ulstu.`is`.airticketrentservice.viewModel.AppViewModelProvider @@ -97,34 +68,6 @@ fun UserList( } } -@OptIn(ExperimentalMaterial3Api::class) -@Composable -private fun DismissBackground(dismissState: DismissState) { - val color = when (dismissState.dismissDirection) { - DismissDirection.StartToEnd -> Color.Transparent - DismissDirection.EndToStart -> Color(0xFFFF1744) - null -> Color.Transparent - } - val direction = dismissState.dismissDirection - - Row( - modifier = Modifier - .fillMaxSize() - .background(color) - .padding(12.dp, 8.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.End - ) { - if (direction == DismissDirection.EndToStart) { - Icon( - Icons.Default.Delete, - contentDescription = "delete", - tint = Color.White - ) - } - } -} - @OptIn(ExperimentalMaterial3Api::class) @Composable private fun SwipeToDelete( @@ -135,12 +78,8 @@ private fun SwipeToDelete( SwipeToDismiss( modifier = Modifier.zIndex(1f), state = dismissState, - directions = setOf( - DismissDirection.EndToStart - ), - background = { - DismissBackground(dismissState) - }, + directions = setOf(), + background = {}, dismissContent = { UserListItem(user = user, modifier = Modifier @@ -173,11 +112,6 @@ private fun UserList( val dismissState: DismissState = rememberDismissState( positionalThreshold = { 200.dp.toPx() } ) - - if (dismissState.isDismissed(direction = DismissDirection.EndToStart)) { - onSwipe(user) - } - SwipeToDelete( dismissState = dismissState, user = user, @@ -195,7 +129,8 @@ private fun UserListItem( ) { Card( modifier = modifier.fillMaxWidth(), - elevation = CardDefaults.cardElevation(defaultElevation = 2.dp) + elevation = CardDefaults.cardElevation(defaultElevation = 2.dp), + colors = CardDefaults.cardColors(colorResource(id = R.color.lightlightBlue)) ) { Column( modifier = modifier.padding(all = 10.dp) diff --git a/app/src/main/java/ru/ulstu/is/airticketrentservice/viewModel/UsersRentsViewModel.kt b/app/src/main/java/ru/ulstu/is/airticketrentservice/viewModel/UsersRentsViewModel.kt index 755f3a4..433f7e8 100644 --- a/app/src/main/java/ru/ulstu/is/airticketrentservice/viewModel/UsersRentsViewModel.kt +++ b/app/src/main/java/ru/ulstu/is/airticketrentservice/viewModel/UsersRentsViewModel.kt @@ -7,8 +7,13 @@ import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import ru.ulstu.`is`.airticketrentservice.database.AppContainer +import ru.ulstu.`is`.airticketrentservice.database.AppDataContainer import ru.ulstu.`is`.airticketrentservice.database.models.Rent import ru.ulstu.`is`.airticketrentservice.database.repository.RentRepository import ru.ulstu.`is`.airticketrentservice.database.repository.UserRepository @@ -18,7 +23,6 @@ class UsersRentsViewModel( private val userRepository: UserRepository, private val rentRepository: RentRepository ) : ViewModel() { - var userRentsUiState by mutableStateOf(UserRentsUiState()) private set @@ -37,6 +41,17 @@ class UsersRentsViewModel( } } + fun refreshRents() { + viewModelScope.launch { + withContext(Dispatchers.IO) { + val rents = userRepository.getUserRents(userUid) + launch(Dispatchers.Main) { + userRentsUiState = UserRentsUiState(rents) + } + } + } + } + suspend fun deleteRent(rent: Rent) { rentRepository.deleteRent(rent) } diff --git a/server/data.json b/server/data.json index 01e61af..99b4372 100644 --- a/server/data.json +++ b/server/data.json @@ -42,12 +42,6 @@ "flightId": 9, "id": 7 }, - { - "passengers_count": 6, - "ticket_cost": 106800, - "flightId": 9, - "id": 8 - }, { "passengers_count": 6, "ticket_cost": 106800, @@ -131,6 +125,12 @@ "ticket_cost": 10000, "flightId": 2, "id": 22 + }, + { + "passengers_count": 6, + "ticket_cost": 6000, + "flightId": 2, + "id": 23 } ], "flights": [ @@ -229,16 +229,6 @@ "role": "User", "id": 4 }, - { - "surname": "ыщылы", - "name": "шчшчгч", - "patronymic": "шчшчшч", - "date_of_birth": "10-12-2015", - "email": "aa@mail.ru", - "password": "aaa", - "role": "User", - "id": 5 - }, { "surname": "фффф", "name": "ффф", @@ -271,29 +261,23 @@ } ], "rents": [ - { + { "id": 1, "status": "Ожидает подтверждения", "userId": 2, "ticketId": 1 }, - { + { "id": 2, - "status": "Подтверждено", + "status": "Ожидает подтверждения", "userId": 2, "ticketId": 2 }, - { + { + "id": 3, "status": "Ожидает подтверждения", "userId": 2, - "ticketId": 21, - "id": 3 - }, - { - "status": "Ожидает подтверждения", - "userId": 2, - "ticketId": 22, - "id": 4 + "ticketId": 3 } ] } \ No newline at end of file diff --git a/server/data.json.bak b/server/data.json.bak index fca779f..ddeb29a 100644 --- a/server/data.json.bak +++ b/server/data.json.bak @@ -42,12 +42,6 @@ "flightId": 9, "id": 7 }, - { - "passengers_count": 6, - "ticket_cost": 106800, - "flightId": 9, - "id": 8 - }, { "passengers_count": 6, "ticket_cost": 106800, @@ -125,6 +119,18 @@ "ticket_cost": 3000, "flightId": 2, "id": 21 + }, + { + "passengers_count": 10, + "ticket_cost": 10000, + "flightId": 2, + "id": 22 + }, + { + "passengers_count": 6, + "ticket_cost": 6000, + "flightId": 2, + "id": 23 } ], "flights": [ @@ -201,7 +207,7 @@ "date_of_birth": "7-11-2003", "email": "usertt@mail.ru", "password": "usertt", - "role": "Admin" + "role": "User" }, { "surname": "а", @@ -223,16 +229,6 @@ "role": "User", "id": 4 }, - { - "surname": "ыщылы", - "name": "шчшчгч", - "patronymic": "шчшчшч", - "date_of_birth": "10-12-2015", - "email": "aa@mail.ru", - "password": "aaa", - "role": "User", - "id": 5 - }, { "surname": "фффф", "name": "ффф", @@ -252,26 +248,17 @@ "password": "kkk", "role": "User", "id": 7 + }, + { + "id": 8, + "surname": "Артамонова", + "name": "Татьяна", + "patronymic": "Валерьевна", + "date_of_birth": "7-11-2003", + "email": "admin@mail.ru", + "password": "admin", + "role": "Admin" } ], - "rents": [ - { - "id": 1, - "status": "Ожидает подтверждения", - "userId": 2, - "ticketId": 1 - }, - { - "id": 2, - "status": "Подтверждено", - "userId": 2, - "ticketId": 2 - }, - { - "status": "Ожидает подтверждения", - "userId": 2, - "ticketId": 21, - "id": 3 - } - ] + "rents": [] } \ No newline at end of file