From a39fc9ab15587419ac2ffb932011703193a030bb Mon Sep 17 00:00:00 2001 From: student-d-sherstnev Date: Wed, 25 Feb 2026 16:58:19 +0300 Subject: [PATCH] room booking --- .../java/ru/myitschool/work/core/Constants.kt | 3 +- .../work/data/dto/AuthRequestDto.kt | 2 + .../work/data/dto/BookRequestDto.kt | 2 +- .../work/data/dto/RoomBookingRequestDto.kt | 12 +++ .../work/data/repo/AuthRepository.kt | 23 ++++ .../work/data/repo/RoomBookingRepository.kt | 32 ++++++ .../work/data/source/NetworkDataSource.kt | 39 +++++++ ...ase.kt => CheckAndSaveAuthTokenUseCase.kt} | 2 +- ...tUseCase.kt => CheckCredsFormatUseCase.kt} | 2 +- .../{GetCodeUseCase.kt => GetTokenUseCase.kt} | 2 +- .../domain/book/entities/BookRequestData.kt | 2 +- .../domain/room/DeleteRoomBookingsUseCase.kt | 11 ++ .../work/domain/room/GetRoleUseCase.kt | 11 ++ .../domain/room/GetRoomBookingsUseCase.kt | 12 +++ .../domain/room/SendRoomBookingUseCase.kt | 13 +++ .../work/ui/nav/RoomScreenDestination.kt | 6 ++ .../work/ui/screen/NavigationGraph.kt | 13 ++- .../work/ui/screen/auth/AuthViewModel.kt | 8 +- .../work/ui/screen/book/BookIntent.kt | 2 +- .../work/ui/screen/book/BookScreen.kt | 4 +- .../work/ui/screen/room/RoomIntent.kt | 5 +- .../work/ui/screen/room/RoomViewModel.kt | 100 ++++++++++++++++++ 22 files changed, 288 insertions(+), 18 deletions(-) create mode 100644 app/src/main/java/ru/myitschool/work/data/dto/RoomBookingRequestDto.kt create mode 100644 app/src/main/java/ru/myitschool/work/data/repo/RoomBookingRepository.kt rename app/src/main/java/ru/myitschool/work/domain/auth/{CheckAndSaveAuthCodeUseCase.kt => CheckAndSaveAuthTokenUseCase.kt} (91%) rename app/src/main/java/ru/myitschool/work/domain/auth/{CheckCodeFormatUseCase.kt => CheckCredsFormatUseCase.kt} (97%) rename app/src/main/java/ru/myitschool/work/domain/auth/{GetCodeUseCase.kt => GetTokenUseCase.kt} (90%) create mode 100644 app/src/main/java/ru/myitschool/work/domain/room/DeleteRoomBookingsUseCase.kt create mode 100644 app/src/main/java/ru/myitschool/work/domain/room/GetRoleUseCase.kt create mode 100644 app/src/main/java/ru/myitschool/work/domain/room/GetRoomBookingsUseCase.kt create mode 100644 app/src/main/java/ru/myitschool/work/domain/room/SendRoomBookingUseCase.kt create mode 100644 app/src/main/java/ru/myitschool/work/ui/nav/RoomScreenDestination.kt diff --git a/app/src/main/java/ru/myitschool/work/core/Constants.kt b/app/src/main/java/ru/myitschool/work/core/Constants.kt index 105d228..6121f27 100644 --- a/app/src/main/java/ru/myitschool/work/core/Constants.kt +++ b/app/src/main/java/ru/myitschool/work/core/Constants.kt @@ -1,10 +1,11 @@ package ru.myitschool.work.core object Constants { - const val HOST = "http://10.0.0.103:49165" + const val HOST = "http://10.0.0.12:49165" const val AUTH_URL = "/login" const val INFO_URL = "/info" const val BOOKING_URL = "/booking" const val BOOK_URL = "/book" + const val ROOM_BOOKING_URL = "/room/booking" const val AUTH_DELAY = 60 } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/data/dto/AuthRequestDto.kt b/app/src/main/java/ru/myitschool/work/data/dto/AuthRequestDto.kt index 8c877e9..4481356 100644 --- a/app/src/main/java/ru/myitschool/work/data/dto/AuthRequestDto.kt +++ b/app/src/main/java/ru/myitschool/work/data/dto/AuthRequestDto.kt @@ -17,4 +17,6 @@ data class AuthResponseDto( val token: String, @SerialName("expired") val expired: Int, + @SerialName("role") + val role: String ) \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/data/dto/BookRequestDto.kt b/app/src/main/java/ru/myitschool/work/data/dto/BookRequestDto.kt index 759ffc5..0aae4be 100644 --- a/app/src/main/java/ru/myitschool/work/data/dto/BookRequestDto.kt +++ b/app/src/main/java/ru/myitschool/work/data/dto/BookRequestDto.kt @@ -8,5 +8,5 @@ data class BookRequestDto( @SerialName("date") val date: String, @SerialName("placeId") - val placeId: String, + val placeId: Int, ) \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/data/dto/RoomBookingRequestDto.kt b/app/src/main/java/ru/myitschool/work/data/dto/RoomBookingRequestDto.kt new file mode 100644 index 0000000..d7bfe63 --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/data/dto/RoomBookingRequestDto.kt @@ -0,0 +1,12 @@ +package ru.myitschool.work.data.dto + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class RoomBookingRequestDto( + @SerialName("roomId") + val roomId: Int, + @SerialName("date") + val date: String, +) \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/data/repo/AuthRepository.kt b/app/src/main/java/ru/myitschool/work/data/repo/AuthRepository.kt index 8dffc44..0f07993 100644 --- a/app/src/main/java/ru/myitschool/work/data/repo/AuthRepository.kt +++ b/app/src/main/java/ru/myitschool/work/data/repo/AuthRepository.kt @@ -16,8 +16,12 @@ import ru.myitschool.work.data.source.NetworkDataSource object AuthRepository { private const val STORE = "AUTH-STORE" private const val TOKEN_KEY = "TOKEN" + private const val ROLE_KEY = "ROLE" + private var tokenCache: String? = null + private var roleCache: String? = null + suspend fun checkAndSave(login: String, password: String): Result { val data = AuthRequestDto(login=login, password=password) @@ -29,6 +33,10 @@ object AuthRepository { val prefKey = stringPreferencesKey(TOKEN_KEY) preferences[prefKey] = encryptedTokenCache } + App.context.userDataStore.edit { preferences -> + val prefKey = stringPreferencesKey(ROLE_KEY) + preferences[prefKey] = success.role + } } } } @@ -47,12 +55,27 @@ object AuthRepository { return null } + suspend fun getRole(): String? { + if (roleCache == null) { + roleCache = App.context.userDataStore.data + .firstOrNull() + ?.let { preferences -> + preferences[stringPreferencesKey(ROLE_KEY)] + } + } + return roleCache + } + suspend fun logout() { tokenCache = null App.context.userDataStore.edit { preferences -> val prefKey = stringPreferencesKey(TOKEN_KEY) preferences.remove(prefKey) } + App.context.userDataStore.edit { preferences -> + val prefKey = stringPreferencesKey(ROLE_KEY) + preferences.remove(prefKey) + } } private val Context.userDataStore: DataStore by preferencesDataStore(name = STORE) diff --git a/app/src/main/java/ru/myitschool/work/data/repo/RoomBookingRepository.kt b/app/src/main/java/ru/myitschool/work/data/repo/RoomBookingRepository.kt new file mode 100644 index 0000000..545c778 --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/data/repo/RoomBookingRepository.kt @@ -0,0 +1,32 @@ +package ru.myitschool.work.data.repo + +import ru.myitschool.work.data.dto.BookRequestDto +import ru.myitschool.work.data.dto.RoomBookingRequestDto +import ru.myitschool.work.data.source.NetworkDataSource +import ru.myitschool.work.domain.room.entities.RoomEntity + +class RoomBookingRepository( + private val authRepository: AuthRepository +) { + suspend fun getRoomBookings(): Result { + val token = authRepository.getToken() ?: return getNoAuthResult() + return NetworkDataSource.getRoomBookings(token).mapCatching { dto -> + RoomEntity(dto) + } + } + + suspend fun deleteRoomBooking(roomId: Int, date: String): Result { + val token = authRepository.getToken() ?: return getNoAuthResult() + val data = RoomBookingRequestDto(roomId = roomId, date = date) + return NetworkDataSource.deleteRoomBooking(token, data) + } + + suspend fun sendRoomBooking(roomId: Int, date: String): Result { + val token = authRepository.getToken() ?: return getNoAuthResult() + val dto = BookRequestDto(date, roomId) + return NetworkDataSource.addBook(token, dto) + } + private fun getNoAuthResult() = Result.failure( + IllegalStateException("No auth") + ) +} \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/data/source/NetworkDataSource.kt b/app/src/main/java/ru/myitschool/work/data/source/NetworkDataSource.kt index dee42cb..c7b2798 100644 --- a/app/src/main/java/ru/myitschool/work/data/source/NetworkDataSource.kt +++ b/app/src/main/java/ru/myitschool/work/data/source/NetworkDataSource.kt @@ -4,6 +4,7 @@ import io.ktor.client.HttpClient import io.ktor.client.call.body import io.ktor.client.engine.cio.CIO import io.ktor.client.plugins.contentnegotiation.ContentNegotiation +import io.ktor.client.request.delete import io.ktor.client.request.get import io.ktor.client.request.headers import io.ktor.client.request.post @@ -21,6 +22,7 @@ import ru.myitschool.work.data.dto.AuthRequestDto import ru.myitschool.work.data.dto.AuthResponseDto import ru.myitschool.work.data.dto.PlaceDto import ru.myitschool.work.data.dto.BookRequestDto +import ru.myitschool.work.data.dto.RoomBookingRequestDto import ru.myitschool.work.data.dto.UserDto import ru.myitschool.work.data.repo.AuthRepository @@ -114,5 +116,42 @@ object NetworkDataSource { } } + suspend fun getRoomBookings(token: String): Result> = withContext(Dispatchers.IO) { + return@withContext runCatching { + val response = client.get(getUrl(Constants.ROOM_BOOKING_URL)) { + headers { + append("Authorization", "Bearer $token") + } + } + if (response.status == HttpStatusCode.OK) { + response.body>() + } else { + if (response.status == HttpStatusCode.Unauthorized) { + AuthRepository.logout() + } + error(response.bodyAsText()) + } + } + } + + suspend fun deleteRoomBooking(token: String, data: RoomBookingRequestDto): Result = withContext(Dispatchers.IO) { + return@withContext runCatching { + val response = client.delete(getUrl(Constants.ROOM_BOOKING_URL)) { + headers { + append("Authorization", "Bearer $token") + } + setBody(data) + } + if (response.status == HttpStatusCode.OK) { + true + } else { + if (response.status == HttpStatusCode.Unauthorized) { + AuthRepository.logout() + } + error(response.bodyAsText()) + } + } + } + private fun getUrl(targetUrl: String) = "${Constants.HOST}/api$targetUrl" } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/domain/auth/CheckAndSaveAuthCodeUseCase.kt b/app/src/main/java/ru/myitschool/work/domain/auth/CheckAndSaveAuthTokenUseCase.kt similarity index 91% rename from app/src/main/java/ru/myitschool/work/domain/auth/CheckAndSaveAuthCodeUseCase.kt rename to app/src/main/java/ru/myitschool/work/domain/auth/CheckAndSaveAuthTokenUseCase.kt index d246c4f..fec73db 100644 --- a/app/src/main/java/ru/myitschool/work/domain/auth/CheckAndSaveAuthCodeUseCase.kt +++ b/app/src/main/java/ru/myitschool/work/domain/auth/CheckAndSaveAuthTokenUseCase.kt @@ -3,7 +3,7 @@ package ru.myitschool.work.domain.auth import ru.myitschool.work.data.dto.AuthResponseDto import ru.myitschool.work.data.repo.AuthRepository -class CheckAndSaveAuthCodeUseCase( +class CheckAndSaveAuthTokenUseCase( private val repository: AuthRepository ) { suspend operator fun invoke( diff --git a/app/src/main/java/ru/myitschool/work/domain/auth/CheckCodeFormatUseCase.kt b/app/src/main/java/ru/myitschool/work/domain/auth/CheckCredsFormatUseCase.kt similarity index 97% rename from app/src/main/java/ru/myitschool/work/domain/auth/CheckCodeFormatUseCase.kt rename to app/src/main/java/ru/myitschool/work/domain/auth/CheckCredsFormatUseCase.kt index c12813f..3a7b743 100644 --- a/app/src/main/java/ru/myitschool/work/domain/auth/CheckCodeFormatUseCase.kt +++ b/app/src/main/java/ru/myitschool/work/domain/auth/CheckCredsFormatUseCase.kt @@ -1,6 +1,6 @@ package ru.myitschool.work.domain.auth -class CheckCodeFormatUseCase { +class CheckCredsFormatUseCase { operator fun invoke( login: String, password: String ): Boolean { diff --git a/app/src/main/java/ru/myitschool/work/domain/auth/GetCodeUseCase.kt b/app/src/main/java/ru/myitschool/work/domain/auth/GetTokenUseCase.kt similarity index 90% rename from app/src/main/java/ru/myitschool/work/domain/auth/GetCodeUseCase.kt rename to app/src/main/java/ru/myitschool/work/domain/auth/GetTokenUseCase.kt index f3a3517..2a5b766 100644 --- a/app/src/main/java/ru/myitschool/work/domain/auth/GetCodeUseCase.kt +++ b/app/src/main/java/ru/myitschool/work/domain/auth/GetTokenUseCase.kt @@ -2,7 +2,7 @@ package ru.myitschool.work.domain.auth import ru.myitschool.work.data.repo.AuthRepository -class GetCodeUseCase( +class GetTokenUseCase( private val repository: AuthRepository ) { suspend operator fun invoke(): String? { diff --git a/app/src/main/java/ru/myitschool/work/domain/book/entities/BookRequestData.kt b/app/src/main/java/ru/myitschool/work/domain/book/entities/BookRequestData.kt index 431a9ad..b39bb37 100644 --- a/app/src/main/java/ru/myitschool/work/domain/book/entities/BookRequestData.kt +++ b/app/src/main/java/ru/myitschool/work/domain/book/entities/BookRequestData.kt @@ -2,5 +2,5 @@ package ru.myitschool.work.domain.book.entities data class BookRequestData( val date: String, - val placeId: String + val placeId: Int ) \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/domain/room/DeleteRoomBookingsUseCase.kt b/app/src/main/java/ru/myitschool/work/domain/room/DeleteRoomBookingsUseCase.kt new file mode 100644 index 0000000..6cd5faa --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/domain/room/DeleteRoomBookingsUseCase.kt @@ -0,0 +1,11 @@ +package ru.myitschool.work.domain.room + +import ru.myitschool.work.data.repo.RoomBookingRepository + +class DeleteRoomBookingsUseCase( + private val repository: RoomBookingRepository +) { + suspend operator fun invoke(roomId: Int, date: String): Result { + return repository.deleteRoomBooking(roomId = roomId, date = date) + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/domain/room/GetRoleUseCase.kt b/app/src/main/java/ru/myitschool/work/domain/room/GetRoleUseCase.kt new file mode 100644 index 0000000..43e9b9a --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/domain/room/GetRoleUseCase.kt @@ -0,0 +1,11 @@ +package ru.myitschool.work.domain.room + +import ru.myitschool.work.data.repo.AuthRepository + +class GetRoleUseCase( + private val repository: AuthRepository +) { + suspend operator fun invoke(): String? { + return repository.getRole() + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/domain/room/GetRoomBookingsUseCase.kt b/app/src/main/java/ru/myitschool/work/domain/room/GetRoomBookingsUseCase.kt new file mode 100644 index 0000000..8fed7de --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/domain/room/GetRoomBookingsUseCase.kt @@ -0,0 +1,12 @@ +package ru.myitschool.work.domain.room + +import ru.myitschool.work.data.repo.RoomBookingRepository +import ru.myitschool.work.domain.room.entities.RoomEntity + +class GetRoomBookingsUseCase( + private val repository: RoomBookingRepository +) { + suspend operator fun invoke(): Result { + return repository.getRoomBookings() + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/domain/room/SendRoomBookingUseCase.kt b/app/src/main/java/ru/myitschool/work/domain/room/SendRoomBookingUseCase.kt new file mode 100644 index 0000000..d50e71c --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/domain/room/SendRoomBookingUseCase.kt @@ -0,0 +1,13 @@ +package ru.myitschool.work.domain.room + +import ru.myitschool.work.data.repo.RoomBookingRepository + +class SendRoomBookingRequestUseCase( + private val repository: RoomBookingRepository +) { + suspend operator fun invoke(roomId: Int, date: String): Result { + return repository.sendRoomBooking(roomId, date).mapCatching { success -> + if (!success) error("Book error") + } + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/nav/RoomScreenDestination.kt b/app/src/main/java/ru/myitschool/work/ui/nav/RoomScreenDestination.kt new file mode 100644 index 0000000..3d6a81c --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/ui/nav/RoomScreenDestination.kt @@ -0,0 +1,6 @@ +package ru.myitschool.work.ui.nav + +import kotlinx.serialization.Serializable + +@Serializable +data object RoomScreenDestination: AppDestination \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/screen/NavigationGraph.kt b/app/src/main/java/ru/myitschool/work/ui/screen/NavigationGraph.kt index a7fedb0..1b6a611 100644 --- a/app/src/main/java/ru/myitschool/work/ui/screen/NavigationGraph.kt +++ b/app/src/main/java/ru/myitschool/work/ui/screen/NavigationGraph.kt @@ -14,14 +14,17 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import ru.myitschool.work.data.repo.AuthRepository -import ru.myitschool.work.domain.auth.GetCodeUseCase +import ru.myitschool.work.domain.auth.GetTokenUseCase +import ru.myitschool.work.domain.room.GetRoleUseCase import ru.myitschool.work.ui.nav.AppDestination import ru.myitschool.work.ui.nav.AuthScreenDestination import ru.myitschool.work.ui.nav.BookScreenDestination import ru.myitschool.work.ui.nav.MainScreenDestination +import ru.myitschool.work.ui.nav.RoomScreenDestination import ru.myitschool.work.ui.screen.auth.AuthScreen import ru.myitschool.work.ui.screen.book.BookScreen import ru.myitschool.work.ui.screen.main.MainScreen +import ru.myitschool.work.ui.screen.room.RoomScreen @Composable fun AppNavHost( @@ -30,9 +33,12 @@ fun AppNavHost( ) { var destination by remember { mutableStateOf(null) } LaunchedEffect(Unit) { - val code = GetCodeUseCase(AuthRepository).invoke() + val code = GetTokenUseCase(AuthRepository).invoke() + val role = GetRoleUseCase(AuthRepository).invoke() destination = if (code == null) { AuthScreenDestination + } else if (role == "room") { + RoomScreenDestination } else { MainScreenDestination } @@ -54,6 +60,9 @@ fun AppNavHost( composable { BookScreen(navController = navController) } + composable { + RoomScreen(navController = navController) + } } } } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/screen/auth/AuthViewModel.kt b/app/src/main/java/ru/myitschool/work/ui/screen/auth/AuthViewModel.kt index 2a33de1..4fa6790 100644 --- a/app/src/main/java/ru/myitschool/work/ui/screen/auth/AuthViewModel.kt +++ b/app/src/main/java/ru/myitschool/work/ui/screen/auth/AuthViewModel.kt @@ -12,13 +12,13 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import ru.myitschool.work.core.Constants import ru.myitschool.work.data.repo.AuthRepository -import ru.myitschool.work.domain.auth.CheckAndSaveAuthCodeUseCase -import ru.myitschool.work.domain.auth.CheckCodeFormatUseCase +import ru.myitschool.work.domain.auth.CheckAndSaveAuthTokenUseCase +import ru.myitschool.work.domain.auth.CheckCredsFormatUseCase import ru.myitschool.work.ui.nav.MainScreenDestination class AuthViewModel : ViewModel() { - private val checkCodeFormatUseCase by lazy { CheckCodeFormatUseCase() } - private val checkAndSaveAuthCodeUseCase by lazy { CheckAndSaveAuthCodeUseCase(AuthRepository) } + private val checkCodeFormatUseCase by lazy { CheckCredsFormatUseCase() } + private val checkAndSaveAuthCodeUseCase by lazy { CheckAndSaveAuthTokenUseCase(AuthRepository) } private val _uiState = MutableStateFlow( AuthState.Data( isEnabledSend = false, diff --git a/app/src/main/java/ru/myitschool/work/ui/screen/book/BookIntent.kt b/app/src/main/java/ru/myitschool/work/ui/screen/book/BookIntent.kt index 9269095..b084f65 100644 --- a/app/src/main/java/ru/myitschool/work/ui/screen/book/BookIntent.kt +++ b/app/src/main/java/ru/myitschool/work/ui/screen/book/BookIntent.kt @@ -4,6 +4,6 @@ sealed interface BookIntent { data object Refresh: BookIntent data class Add( val date: String, - val placeId: String + val placeId: Int ): BookIntent } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/screen/book/BookScreen.kt b/app/src/main/java/ru/myitschool/work/ui/screen/book/BookScreen.kt index 60842f3..c707dbf 100644 --- a/app/src/main/java/ru/myitschool/work/ui/screen/book/BookScreen.kt +++ b/app/src/main/java/ru/myitschool/work/ui/screen/book/BookScreen.kt @@ -170,7 +170,7 @@ private fun ContentState( mutableIntStateOf(startDestination.index) } var selectedPlaceId by rememberSaveable { - mutableStateOf(null) + mutableStateOf(null) } Box { Column { @@ -213,7 +213,7 @@ private fun ContentState( startDestination = startDestination, state = state, onPlaceSelected = { id -> - selectedPlaceId = id + selectedPlaceId = id.toInt() } ) } diff --git a/app/src/main/java/ru/myitschool/work/ui/screen/room/RoomIntent.kt b/app/src/main/java/ru/myitschool/work/ui/screen/room/RoomIntent.kt index 11ff17b..95f0cd2 100644 --- a/app/src/main/java/ru/myitschool/work/ui/screen/room/RoomIntent.kt +++ b/app/src/main/java/ru/myitschool/work/ui/screen/room/RoomIntent.kt @@ -2,7 +2,6 @@ package ru.myitschool.work.ui.screen.room sealed interface RoomIntent { data object Refresh: RoomIntent - data class Booking(val placeId: Int): RoomIntent - data object Book: RoomIntent - data object UnBook: RoomIntent + data class Booking(val placeId: Int, val date: String): RoomIntent + data class UnBook(val placeId: Int, val date: String): RoomIntent } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/screen/room/RoomViewModel.kt b/app/src/main/java/ru/myitschool/work/ui/screen/room/RoomViewModel.kt index a9b42fc..89cc022 100644 --- a/app/src/main/java/ru/myitschool/work/ui/screen/room/RoomViewModel.kt +++ b/app/src/main/java/ru/myitschool/work/ui/screen/room/RoomViewModel.kt @@ -1,7 +1,107 @@ package ru.myitschool.work.ui.screen.room import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import ru.myitschool.work.data.repo.AuthRepository +import ru.myitschool.work.data.repo.RoomBookingRepository +import ru.myitschool.work.domain.room.DeleteRoomBookingsUseCase +import ru.myitschool.work.domain.room.GetRoomBookingsUseCase +import ru.myitschool.work.domain.room.SendRoomBookingRequestUseCase class RoomViewModel : ViewModel() { + private val roomBookingRepository = RoomBookingRepository( + AuthRepository + ) + private val getRoomBookingsDataUseCase by lazy { + GetRoomBookingsUseCase( + RoomBookingRepository( + AuthRepository + ) + ) + } + private val deleteRoomBookingRequestUseCase by lazy { + DeleteRoomBookingsUseCase( + roomBookingRepository + ) + } + + private val sendRoomBookingRequestUseCase by lazy { + SendRoomBookingRequestUseCase( + roomBookingRepository + ) + } + private val _uiState = MutableStateFlow(RoomState.Loading) + val uiState: StateFlow = _uiState.asStateFlow() + + init { + refresh() + } + + fun onIntent(intent: RoomIntent) { + when (intent) { + is RoomIntent.Refresh -> { + refresh() + } + + is RoomIntent.Booking -> { + viewModelScope.launch { + sendRoomBookingRequestUseCase.invoke( + intent.placeId, + intent.date + ).fold( + onSuccess = { +// _actionFlow.emit(BookAction.BackWithSuccess) + refresh() + }, + onFailure = { error -> + error.printStackTrace() + } + ) + } + } + + is RoomIntent.UnBook -> { + viewModelScope.launch { + deleteRoomBookingRequestUseCase.invoke( + intent.placeId, + intent.date + ).fold( + onSuccess = { +// _actionFlow.emit(BookAction.BackWithSuccess) + refresh() + }, + onFailure = { error -> + error.printStackTrace() + } + ) + } + } + } + } + + private fun refresh() { + viewModelScope.launch { + _uiState.update { RoomState.Loading } + _uiState.update { + getRoomBookingsDataUseCase.invoke().fold( + onSuccess = { data -> + RoomState.Data( + data = data + ) + }, + onFailure = { error -> + RoomState.Error( + error = error.message.orEmpty() + ) + } + ) + } + } + } } \ No newline at end of file