Compare commits

...

2 Commits

16 changed files with 244 additions and 915 deletions

View File

@ -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<Ticket> = ticketDao.getFlightsTickets(flightId)
suspend fun clearTickets() = ticketDao.deleteAll()
suspend fun insertTickets(tickets: List<Ticket>) =
ticketDao.insert(*tickets.toTypedArray())[0]
ticketDao.insert(*tickets.toTypedArray())
}

View File

@ -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,

View File

@ -1,25 +1,18 @@
package ru.ulstu.`is`.airticketrentservice.navigation
import android.content.res.Configuration
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.compose.animation.AnimatedVisibility
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.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
@ -28,21 +21,22 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import androidx.navigation.NavDestination
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import ru.ulstu.`is`.airticketrentservice.R
import ru.ulstu.`is`.airticketrentservice.ui.theme.AirTicketRentServiceTheme
import ru.ulstu.`is`.airticketrentservice.viewModel.AppViewModelProvider
import ru.ulstu.`is`.airticketrentservice.viewModel.CurrentUserViewModel
@Composable
fun BottomBar(navController: NavHostController){
fun BottomBar(navController: NavHostController, currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory)){
val screens = listOf(
BottomBarScreen.MainPage,
BottomBarScreen.Profile,
@ -65,11 +59,14 @@ fun BottomBar(navController: NavHostController){
.clip(shape = RoundedCornerShape(20.dp))
) {
screens.forEach { screen ->
AddItem(
screen = screen,
currentDestination = currentDestination,
navController = navController
)
currentUserViewModel.user?.role?.let {
AddItem(
screen = screen,
currentDestination = currentDestination,
navController = navController,
userRole = it
)
}
}
}
}
@ -80,34 +77,37 @@ fun BottomBar(navController: NavHostController){
fun RowScope.AddItem(
screen: BottomBarScreen,
currentDestination: NavDestination?,
navController: NavController
navController: NavController,
userRole: String
){
val isAdmin = userRole == "Admin"
val selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true
val background = if (selected) Color(0xFFFFFFFF) else Color.Transparent
Box(
modifier = Modifier
.height(40.dp)
.clip(CircleShape)
.background(background)
.clickable(onClick = {
navController.navigate(screen.route) {
popUpTo(navController.graph.findStartDestination().id)
launchSingleTop = true
}
})
) {
Row(
modifier = Modifier.padding(start = 47.dp, end = 46.dp),
verticalAlignment = Alignment.CenterVertically,
if (isAdmin || screen != BottomBarScreen.Admin) {
Box(
modifier = Modifier
.height(40.dp)
.clip(CircleShape)
.background(background)
.clickable(onClick = {
navController.navigate(screen.route) {
popUpTo(navController.graph.findStartDestination().id)
launchSingleTop = true
}
})
) {
Icon(
imageVector = screen.icon,
contentDescription = "icon",
tint = Color.DarkGray
)
Row(
modifier = Modifier.padding(start = 47.dp, end = 46.dp, top = 10.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
imageVector = screen.icon,
contentDescription = "icon",
tint = Color.DarkGray
)
}
}
} else {
Text(text = "Недостаточно прав", fontSize = 8.sp, modifier = Modifier.fillMaxWidth().padding(top = 10.dp))
}
}

View File

@ -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 ="",

View File

@ -1,362 +0,0 @@
package ru.ulstu.`is`.airticketrentservice.navigation
import android.annotation.SuppressLint
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.NavigationBarItemDefaults
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModelStore
import androidx.lifecycle.ViewModelStoreOwner
import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavDestination
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import androidx.navigation.navigation
import ru.ulstu.`is`.airticketrentservice.screen.RentList
import ru.ulstu.`is`.airticketrentservice.screen.UserEdit
import ru.ulstu.`is`.airticketrentservice.screen.FlightEdit
import ru.ulstu.`is`.airticketrentservice.R
import ru.ulstu.`is`.airticketrentservice.screen.Admin
import ru.ulstu.`is`.airticketrentservice.screen.FlightInfo
import ru.ulstu.`is`.airticketrentservice.screen.FlightList
import ru.ulstu.`is`.airticketrentservice.screen.FoundFlights
import ru.ulstu.`is`.airticketrentservice.screen.LoadScreen
import ru.ulstu.`is`.airticketrentservice.screen.MainPage
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.TicketEdit
import ru.ulstu.`is`.airticketrentservice.screen.UserList
import ru.ulstu.`is`.airticketrentservice.screen.auth.Login
import ru.ulstu.`is`.airticketrentservice.screen.auth.Registration
import ru.ulstu.`is`.airticketrentservice.viewModel.AppViewModelProvider
import ru.ulstu.`is`.airticketrentservice.viewModel.CurrentUserViewModel
import ru.ulstu.`is`.airticketrentservice.viewModel.FlightEditViewModel
import ru.ulstu.`is`.airticketrentservice.viewModel.FlightListViewModel
import ru.ulstu.`is`.airticketrentservice.viewModel.LoginViewModel
import ru.ulstu.`is`.airticketrentservice.viewModel.RegistrationViewModel
import ru.ulstu.`is`.airticketrentservice.viewModel.RentEditViewModel
import ru.ulstu.`is`.airticketrentservice.viewModel.RentListViewModel
import ru.ulstu.`is`.airticketrentservice.viewModel.TicketEditViewModel
import ru.ulstu.`is`.airticketrentservice.viewModel.UserEditViewModel
import ru.ulstu.`is`.airticketrentservice.viewModel.UserListViewModel
//@OptIn(ExperimentalMaterial3Api::class)
//@Composable
//fun Topbar(
// navController: NavHostController,
// currentScreen: Screen?
//) {
// TopAppBar(
// colors = TopAppBarDefaults.topAppBarColors(
// containerColor = Color.Transparent,
// ),
// title = {},
// navigationIcon = {
// if (
// navController.previousBackStackEntry != null
// && (currentScreen == null || !currentScreen.showInBottomBar)
// ) {
// IconButton(onClick = { navController.navigateUp() }) {
// Icon(
// imageVector = Icons.Filled.ArrowBack,
// contentDescription = null,
// tint = colorResource(R.color.black)
// )
// }
// }
// },
// modifier = Modifier
// .padding(10.dp)
// .clip(RoundedCornerShape(20.dp))
// )
//}
//
//@Composable
//fun Navbar(
// navController: NavHostController,
// currentDestination: NavDestination?
//) {
// NavigationBar(
// Modifier
// .padding(10.dp)
// .clip(RoundedCornerShape(20.dp))) {
// Screen.bottomBarItems.forEach { screen ->
// NavigationBarItem(
// colors = NavigationBarItemDefaults.colors(colorResource(R.color.lightBlue)),
// icon = { Icon(screen.icon, contentDescription = null) },
// label = { Text(stringResource(screen.resourceId)) },
// selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true,
// onClick = {
// navController.navigate(screen.route) {
// popUpTo(navController.graph.findStartDestination().id) {
// saveState = true
// }
// launchSingleTop = true
// restoreState = true
// }
// }
// )
// }
// }
//}
//
//const val USERID_ARGUMENT="userId"
//@Composable
//fun RootNavGraph(
// navController: NavHostController,
// registrationViewModel: RegistrationViewModel= viewModel(factory = AppViewModelProvider.Factory),
// loginViewModel: LoginViewModel = viewModel(factory = AppViewModelProvider.Factory),
// currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory),
//) {
// NavHost(
// navController = navController,
// route = Graph.ROOT,
// startDestination = Graph.AUTHENTICATION
// ) {
// authNavGraph(navController = navController, registrationViewModel, loginViewModel, currentUserViewModel)
// composable(route=Graph.MAIN,
// arguments = listOf(navArgument(USERID_ARGUMENT){
// type= NavType.StringType
// })){
// LoadScreen(
// navController = navController,
// currentUserViewModel = currentUserViewModel
// )
// }
// }
//}
//
//fun NavGraphBuilder.authNavGraph(navController: NavHostController, registrationViewModel: RegistrationViewModel, loginViewModel: LoginViewModel, currentUserViewModel: CurrentUserViewModel){
// navigation(
// route=Graph.AUTHENTICATION,
// startDestination = AuthScreen.Login.route
// ){
// composable(route=AuthScreen.Login.route){
// Login(navController = navController, Modifier, loginViewModel, currentUserViewModel)
// }
// composable(route=AuthScreen.Registration.route){
// Registration(navController = navController, Modifier, registrationViewModel, currentUserViewModel)
// }
// }
//}
//
//sealed class AuthScreen(val route: String){
// object Login : AuthScreen(route = "login")
// object Registration : AuthScreen(route="registration")
//}
//
//@Composable
//fun HomeNavGraph(
// navController: NavHostController,
// currentUserViewModel: CurrentUserViewModel
//) {
// NavHost(
// navController = navController,
// startDestination = Screen.MainPage.route
// ) {
// composable(Screen.MainPage.route) { MainPage(navController) }
// composable(Screen.RentList.route) { RentList(navController) }
// composable(Screen.FlightList.route) { FlightList(navController) }
// composable(Screen.Profile.route) { Profile(navController, currentUserViewModel) }
// composable(Screen.UserList.route) { UserList(navController) }
//// composable(Screen.Login.route) { Login(navController) }
// composable(Screen.MyRents.route) { MyRents(navController) }
//// composable(Screen.Registration.route) { Registration(navController) }
// composable(Screen.Admin.route) { Admin(navController) }
// composable(
// Screen.FlightInfo.route,
// arguments = listOf(navArgument("id") { type = NavType.IntType })
// ) {
// FlightInfo(navController)
// }
// composable(
// Screen.FoundFlights.route,
// arguments = listOf(
// navArgument("from") { type = NavType.StringType },
// navArgument("to") { type = NavType.StringType },
// navArgument("departureDate") { type = NavType.StringType }
// )
// ) {
// FoundFlights(navController)
// }
// composable(
// Screen.UserEdit.route,
// arguments = listOf(navArgument("id") { type = NavType.IntType })
// ) {
// UserEdit(navController)
// }
// composable(
// Screen.FlightEdit.route,
// arguments = listOf(navArgument("id") { type = NavType.IntType })
// ) {
// FlightEdit(navController)
// }
// composable(
// Screen.TicketEdit.route,
// arguments = listOf(navArgument("id") { type = NavType.IntType })
// ) {
// TicketEdit(navController)
// }
//// composable(
//// Screen.MyRents.route,
//// arguments = listOf(navArgument("id") { type = NavType.IntType })
//// ) {
//// MyRents(navController)
//// }
// composable(
// Screen.RentEdit.route,
// arguments = listOf(navArgument("id") { type = NavType.IntType })
// ) {
// RentEdit(navController)
// }
// }
//}
//
//object Graph{
// const val ROOT="root_graph"
// const val AUTHENTICATION="auth_graph"
// const val MAIN="main_graph/{$USERID_ARGUMENT}"
// fun passUserId(userId: String): String{
// return "main_graph/$userId"
// }
//}
//
////@RequiresApi(Build.VERSION_CODES.O)
////@Composable
////fun Navhost(
//// navController: NavHostController,
//// innerPadding: PaddingValues, modifier:
//// Modifier = Modifier,
//// currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory),
//// loginViewModel: LoginViewModel = viewModel(factory = AppViewModelProvider.Factory),
//// registrationViewModel: RegistrationViewModel = viewModel(factory = AppViewModelProvider.Factory),
////) {
//// NavHost(
//// navController,
//// startDestination = Graph.AUTHENTICATION,
//// modifier.padding(innerPadding),
//// route = Graph.ROOT
//// ) {
//// authNavGraph(navController=navController,registrationViewModel,loginViewModel,currentUserViewModel)
//// composable(route=Graph.MAIN,
//// arguments = listOf(navArgument(USERID_ARGUMENT){
//// type= NavType.StringType
//// })
////// composable(Screen.RentList.route) { RentList(navController) }
////// composable(Screen.FlightList.route) { FlightList(navController) }
////// composable(Screen.Profile.route) { Profile(navController) }
////// composable(Screen.UserList.route) { UserList(navController) }
////// composable(Screen.Login.route) { Login(navController) }
////// composable(Screen.MyRents.route) { MyRents(navController) }
////// composable(Screen.Registration.route) { Registration(navController) }
////// composable(Screen.MainPage.route) { MainPage(navController) }
////// composable(Screen.Admin.route) { Admin(navController) }
////// composable(
////// Screen.TicketEdit.route,
////// arguments = listOf(navArgument("id") { type = NavType.IntType })
////// ) {
////// TicketEdit(navController)
////// }
////// composable(
////// Screen.FlightInfo.route,
////// arguments = listOf(navArgument("id") { type = NavType.IntType })
////// ) {
////// FlightInfo(navController)
////// }
////// composable(
////// Screen.FoundFlights.route,
////// arguments = listOf(
////// navArgument("from") { type = NavType.StringType },
////// navArgument("to") { type = NavType.StringType },
////// navArgument("departureDate") { type = NavType.StringType }
////// )
////// ) {
////// FoundFlights(navController)
////// }
////// composable(
////// Screen.UserEdit.route,
////// arguments = listOf(navArgument("id") { type = NavType.IntType })
////// ) {
////// UserEdit(navController)
////// }
////// composable(
////// Screen.FlightEdit.route,
////// arguments = listOf(navArgument("id") { type = NavType.IntType })
////// ) {
////// FlightEdit(navController)
////// }
//////// composable(
//////// Screen.MyRents.route,
//////// arguments = listOf(navArgument("id") { type = NavType.IntType })
//////// ) {
//////// MyRents(navController)
//////// }
////// composable(
////// Screen.RentEdit.route,
////// arguments = listOf(navArgument("id") { type = NavType.IntType })
////// ) {
////// RentEdit(navController)
////// }
//// }
////}
//
//@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
//@RequiresApi(Build.VERSION_CODES.O)
//@Composable
//fun MainNavbar() {
// val navController = rememberNavController()
// val navBackStackEntry by navController.currentBackStackEntryAsState()
// val currentDestination = navBackStackEntry?.destination
// val currentScreen = currentDestination?.route?.let { Screen.getItem(it) }
// val registrationViewModel: RegistrationViewModel= viewModel(factory = AppViewModelProvider.Factory)
// val loginViewModel: LoginViewModel = viewModel(factory = AppViewModelProvider.Factory)
// val currentUserViewModel: CurrentUserViewModel = viewModel(factory = AppViewModelProvider.Factory)
//
// Scaffold(
// topBar = {
// Topbar(navController, currentScreen)
// },
// bottomBar = {
// if (currentScreen == null || currentScreen.showInBottomBar) {
// Navbar(navController, currentDestination)
// }
// }
// ) {
// RootNavGraph(navController, registrationViewModel, loginViewModel, currentUserViewModel)
// }
//}

View File

@ -1,76 +0,0 @@
package ru.ulstu.`is`.airticketrentservice.navigation
import androidx.annotation.StringRes
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.AccountCircle
import androidx.compose.material.icons.filled.AdminPanelSettings
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.Search
import androidx.compose.ui.graphics.vector.ImageVector
import ru.ulstu.`is`.airticketrentservice.R
//enum class Screen(
// val route: String,
// @StringRes val resourceId: Int,
// val icon: ImageVector = Icons.Filled.Favorite,
// val showInBottomBar: Boolean = true
//) {
// Admin(
// "admin", R.string.rent_view_title, Icons.Filled.AdminPanelSettings
// ),
// FlightEdit(
// "flight-edit/{id}", R.string.ticket_view_title, showInBottomBar = false
// ),
// FlightInfo(
// "flight-info/{id}", R.string.ticket_view_title, showInBottomBar = false
// ),
// FlightList(
// "flight-list", R.string.ticket_main_title, showInBottomBar = false
// ),
// FoundFlights(
// "found-flights/{from}-{to}-{departureDate}", R.string.ticket_main_title, showInBottomBar = false
// ),
// MainPage(
// "main", R.string.rent_view_title, Icons.Filled.Search
// ),
// MyRents(
// "my-rents", R.string.ticket_view_title, showInBottomBar = false
// ),
// Profile(
// "profile", R.string.rent_view_title, Icons.Filled.AccountCircle
// ),
// RentEdit(
// "rent-edit/{id}", R.string.ticket_view_title, showInBottomBar = false
// ),
// RentList(
// "rent-list", R.string.ticket_main_title, showInBottomBar = false
// ),
// TicketEdit(
// "ticket-edit/{id}", R.string.ticket_view_title, showInBottomBar = false
// ),
// UserEdit(
// "user-edit/{id}", R.string.ticket_view_title, showInBottomBar = false
// ),
// UserList(
// "user-list", R.string.ticket_main_title, showInBottomBar = false
// ),
// Login(
// "login", R.string.rent_view_title, showInBottomBar = false
// ),
// Registration(
// "registration", R.string.rent_view_title, showInBottomBar = false
// );
//
// companion object {
// val bottomBarItems = listOf(
// MainPage,
// Profile,
// Admin
// )
//
// fun getItem(route: String): Screen? {
// val findRoute = route.split("/").first()
// return values().find { value -> value.route.startsWith(findRoute) }
// }
// }
//}

View File

@ -1,49 +0,0 @@
package ru.ulstu.`is`.airticketrentservice.navigation
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import ru.ulstu.`is`.airticketrentservice.R
//@OptIn(ExperimentalMaterial3Api::class)
//@Composable
//fun TopBar(navController: NavHostController,
// currentScreen: BottomBarScreen?) {
// TopAppBar(
// colors = TopAppBarDefaults.topAppBarColors(
// containerColor = Color.Transparent,
// ),
// title = {},
// actions = {},
// navigationIcon = {
// if (
// navController.previousBackStackEntry != null
// && (currentScreen == null)
// ) {
// IconButton(onClick = { navController.navigateUp() }) {
// Icon(
// imageVector = Icons.Filled.ArrowBack,
// contentDescription = null,
// tint = colorResource(R.color.black)
// )
// }
// }
// },
// modifier = Modifier
// .padding(10.dp)
// .clip(RoundedCornerShape(20.dp))
// )
//}

View File

@ -229,7 +229,7 @@ fun LoadScreen(navController: NavHostController = rememberNavController(),
rentListViewModel: RentListViewModel = viewModel(factory = AppViewModelProvider.Factory)
){
Scaffold(
bottomBar = {BottomBar(navController = navController) },
bottomBar = {BottomBar(navController = navController, currentUserViewModel) },
) {
Modifier
.padding(it)

View File

@ -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: 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)

View File

@ -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("Выйти")
}

View File

@ -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))
}
)
}
}

View File

@ -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)

View File

@ -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)

View File

@ -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)
}

View File

@ -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
}
]
}

View File

@ -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": []
}