diff --git a/app/src/main/java/ru/myitschool/work/domain/entities/BookingEntities.kt b/app/src/main/java/ru/myitschool/work/domain/entities/BookingEntities.kt new file mode 100644 index 0000000..9cc4cad --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/domain/entities/BookingEntities.kt @@ -0,0 +1,6 @@ +package ru.myitschool.work.domain.entities + +data class BookingEntities ( + var roomName : String, + var time: String +) \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/domain/entities/UserEntities.kt b/app/src/main/java/ru/myitschool/work/domain/entities/UserEntities.kt new file mode 100644 index 0000000..23d2aba --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/domain/entities/UserEntities.kt @@ -0,0 +1,7 @@ +package ru.myitschool.work.domain.entities + +data class UserEntities( + val name : String, + var image : Int, + var booking : ArrayList +) 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 01b0f32..9dad87b 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 @@ -15,6 +15,7 @@ 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.screen.auth.AuthScreen +import ru.myitschool.work.ui.screen.book.BookScreen @Composable fun AppNavHost( @@ -39,11 +40,7 @@ fun AppNavHost( } } composable { - Box( - contentAlignment = Alignment.Center - ) { - Text(text = "Hello") - } + BookScreen(navController = navController) } } } \ No newline at end of file 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 new file mode 100644 index 0000000..506f720 --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/ui/screen/book/BookIntent.kt @@ -0,0 +1,6 @@ +package ru.myitschool.work.ui.screen.book + +sealed interface BookIntent { + data class Send(val text: String): BookIntent + data class BookingSelect(val text: String): 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 new file mode 100644 index 0000000..7dc159f --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/ui/screen/book/BookScreen.kt @@ -0,0 +1,215 @@ +package ru.myitschool.work.ui.screen.book; + +import androidx.compose.foundation.layout.Arrangement +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.size +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.selection.selectableGroup +import androidx.compose.material3.Button +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.NavigationBar +import androidx.compose.material3.NavigationBarItem +import androidx.compose.material3.RadioButton +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable; +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel +import androidx.navigation.NavController; +import ru.myitschool.work.R +import ru.myitschool.work.core.TestIds +import ru.myitschool.work.domain.entities.BookingEntities +import ru.myitschool.work.ui.nav.BookScreenDestination +import ru.myitschool.work.ui.nav.MainScreenDestination +import ru.myitschool.work.ui.screen.auth.AuthViewModel + +var selectedTime = mutableStateOf(0) +var selectedBooking = mutableStateOf(0) +var currentTime = mutableStateOf(0) +@Composable +fun BookScreen( + viewModel: BookViewModel = viewModel(), + navController: NavController, + modifier: Modifier = Modifier +) { + val state by viewModel.uiState.collectAsState() + + LaunchedEffect(Unit) { + viewModel.actionFlow.collect { + navController.navigate(MainScreenDestination) + } + } + + // TODO брать данные с сервера + // Иммитация того, что мы взяли данные с сервера + val bookings = arrayListOf( + BookingEntities( + "Рабочее место у окна", + "19.04" + ), + BookingEntities( + "Переговорная комната № 1", + "19.04" + ), + BookingEntities( + "Коворкинг А", + "19.04" + ), + BookingEntities( + "Кабинет № 33", + "20.04" + ), + ) + val options = toMap(bookings) + + Column( + modifier = modifier.fillMaxSize() + ) { +// Text("" + selectedTime.value + "," + currentTime.value + "," + selectedBooking.value) + when (val currentState = state) { + BookState.Data -> { + TabGroup(options.keys) + + var i = 0 + options.keys.forEach { + if (i == currentTime.value) + SelectBooking(options[it]!!) + i ++; + } + + Button( + onClick = { + // TODO Добавить бронирование + viewModel.onIntent(BookIntent.Send("Данные" )) + }, + modifier = Modifier + .testTag(TestIds.Book.BOOK_BUTTON) + ) { + Text(stringResource(R.string.to_book)) + } + } + + BookState.Error -> { + Text( + text = "", + modifier = Modifier + .testTag(TestIds.Book.ERROR) + ) + + Button( + onClick = { }, + modifier = Modifier + .testTag(TestIds.Book.REFRESH_BUTTON) + ) { + Text("") + } + } + + BookState.Loading -> { + CircularProgressIndicator( + modifier = Modifier + .align(Alignment.CenterHorizontally) + .size(64.dp) + ) + } + + BookState.NotData -> { + Text( + text = "", + modifier = Modifier + .testTag(TestIds.Book.EMPTY) + ) + } + } + Button( + onClick = { + navController.navigate(MainScreenDestination) + }, + modifier = Modifier + .testTag(TestIds.Book.BACK_BUTTON) + ) { + Text(stringResource(R.string.back)) + } + } +} + + +@Composable +fun TabGroup(options: Set) { + NavigationBar( + Modifier.fillMaxWidth() + ) { + options.forEachIndexed { index, label -> + NavigationBarItem( + selected = currentTime.value == index, + onClick = { + currentTime.value = index + }, + icon = { + Text( + text = label, + modifier = Modifier + .testTag(TestIds.Book.ITEM_DATE) + ) + }, + modifier = Modifier + .testTag(TestIds.Book.getIdDateItemByPosition(index)) + ) + } + } +} + +@Composable +fun SelectBooking(options: List) { + LazyColumn( + Modifier + .fillMaxWidth() + ) { + options.forEachIndexed { index, label -> + item { + Row( + Modifier + .fillMaxWidth() + .selectableGroup() + .testTag(TestIds.Book.getIdPlaceItemByPosition(index)), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = label, + modifier = Modifier + .testTag(TestIds.Book.ITEM_PLACE_TEXT) + ) + RadioButton( + selected = index == selectedBooking.value && currentTime.value == selectedTime.value, + onClick = { + selectedBooking.value = index + selectedTime.value = currentTime.value + }, + modifier = Modifier + .testTag(TestIds.Book.ITEM_PLACE_SELECTOR) + ) + } + } + } + } +} + +fun toMap(options: List) : Map> { + val map : MutableMap> = mutableMapOf() + options.forEach { + if (map[it.time] == null) map[it.time] = mutableListOf(it.roomName) + else map[it.time]?.add(it.roomName) + } + return map +} \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/screen/book/BookState.kt b/app/src/main/java/ru/myitschool/work/ui/screen/book/BookState.kt new file mode 100644 index 0000000..8b87d87 --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/ui/screen/book/BookState.kt @@ -0,0 +1,8 @@ +package ru.myitschool.work.ui.screen.book + +sealed interface BookState { + object Loading: BookState + object Data: BookState + object Error: BookState + object NotData : BookState +} \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/screen/book/BookViewModel.kt b/app/src/main/java/ru/myitschool/work/ui/screen/book/BookViewModel.kt new file mode 100644 index 0000000..c713202 --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/ui/screen/book/BookViewModel.kt @@ -0,0 +1,31 @@ +package ru.myitschool.work.ui.screen.book + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch + +class BookViewModel : ViewModel() { + private val _uiState = MutableStateFlow(BookState.Data) + val uiState: StateFlow = _uiState.asStateFlow(); + + private val _actionFlow: MutableSharedFlow = MutableSharedFlow() + val actionFlow: SharedFlow = _actionFlow + + fun onIntent(intent: BookIntent) { + when (intent) { + is BookIntent.Send -> { + viewModelScope.launch(Dispatchers.Default) { + _uiState.update { BookState.Loading } + } + } + is BookIntent.BookingSelect -> Unit + } + } +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fa8bda6..5979b52 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -4,4 +4,6 @@ Привет! Введи код для авторизации Код Войти + забронировать + Назад \ No newline at end of file