our commit message
This commit is contained in:
@@ -2,10 +2,7 @@ package ru.myitschool.work.ui.screen
|
|||||||
|
|
||||||
import androidx.compose.animation.EnterTransition
|
import androidx.compose.animation.EnterTransition
|
||||||
import androidx.compose.animation.ExitTransition
|
import androidx.compose.animation.ExitTransition
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
@@ -34,10 +31,21 @@ fun AppNavHost(
|
|||||||
AuthScreen(navController = navController)
|
AuthScreen(navController = navController)
|
||||||
}
|
}
|
||||||
composable<MainScreenDestination> {
|
composable<MainScreenDestination> {
|
||||||
MainScreen(navController = navController)
|
MainScreen(
|
||||||
|
navController = navController,
|
||||||
|
onNavigateToBooking = {
|
||||||
|
navController.navigate(BookScreenDestination)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
composable<BookScreenDestination> {
|
composable<BookScreenDestination> {
|
||||||
BookScreen(navController = navController)
|
BookScreen(
|
||||||
|
onBack = { navController.popBackStack() },
|
||||||
|
onBookingSuccess = {
|
||||||
|
// Возвращаемся на главный экран и обновляем его
|
||||||
|
navController.popBackStack()
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,6 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.platform.testTag
|
import androidx.compose.ui.platform.testTag
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
|||||||
@@ -1,16 +1,168 @@
|
|||||||
package ru.myitschool.work.ui.screen.book
|
package ru.myitschool.work.ui.screen.book
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.navigation.NavController
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
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.selection.selectable
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.RadioButton
|
||||||
|
import androidx.compose.material3.ScrollableTabRow
|
||||||
|
import androidx.compose.material3.Tab
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.testTag
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BookScreen(navController: NavController){
|
fun BookingScreen(
|
||||||
Box(
|
uiState: BookingUiState, // состояние интерфейса
|
||||||
contentAlignment = Alignment.Center
|
onSelectDate: (LocalDate) -> Unit, // callback при выборе даты
|
||||||
|
onSelectPlace: (String) -> Unit, // callback при выборе места
|
||||||
|
onBook: () -> Unit, // callback при бронировании
|
||||||
|
onBack: () -> Unit, // callback при нажатии "Назад"
|
||||||
|
onRefresh: () -> Unit // callback при обновлении
|
||||||
) {
|
) {
|
||||||
Text(text = "Hello")
|
// Сортировка дат по порядку
|
||||||
|
val sortedDates = uiState.dates.sorted()
|
||||||
|
// Фильтрация дат, для которых есть доступные места
|
||||||
|
val availableDates = sortedDates.filter { date -> uiState.places[date]?.isNotEmpty() == true }
|
||||||
|
|
||||||
|
Column(modifier = Modifier.fillMaxSize().padding(16.dp)) {
|
||||||
|
// Вкладки для выбора дат
|
||||||
|
if (availableDates.isNotEmpty()) {
|
||||||
|
ScrollableTabRow(selectedTabIndex = availableDates.indexOf(uiState.selectedDate)) {
|
||||||
|
availableDates.forEachIndexed { index, date ->
|
||||||
|
Tab(
|
||||||
|
selected = date == uiState.selectedDate,
|
||||||
|
onClick = { onSelectDate(date) },
|
||||||
|
text = {
|
||||||
|
Text(
|
||||||
|
text = date.format(DateTimeFormatter.ofPattern("dd.MM")),
|
||||||
|
modifier = Modifier.testTag("book_date_pos_$index")
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier.testTag("book_date")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
// Список мест для выбранной даты
|
||||||
|
val placesForDate = uiState.selectedDate?.let { uiState.places[it] } ?: emptyList()
|
||||||
|
|
||||||
|
if (placesForDate.isNotEmpty()) {
|
||||||
|
Column {
|
||||||
|
placesForDate.forEachIndexed { index, place ->
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 8.dp)
|
||||||
|
.selectable(
|
||||||
|
selected = uiState.selectedPlace == place,
|
||||||
|
onClick = { onSelectPlace(place) }
|
||||||
|
)
|
||||||
|
.testTag("book_place_pos_$index"),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = place,
|
||||||
|
modifier = Modifier.weight(1f).testTag("book_place_text")
|
||||||
|
)
|
||||||
|
RadioButton(
|
||||||
|
selected = uiState.selectedPlace == place,
|
||||||
|
onClick = { onSelectPlace(place) },
|
||||||
|
modifier = Modifier.testTag("book_place_selector")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// пустой список (все забронировано)
|
||||||
|
if (availableDates.isEmpty() && !uiState.isError) {
|
||||||
|
Text(
|
||||||
|
text = "Всё забронировано",
|
||||||
|
modifier = Modifier.testTag("book_empty")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ошибка
|
||||||
|
if (uiState.isError) {
|
||||||
|
Text(
|
||||||
|
text = uiState.errorMessage ?: "Ошибка загрузки",
|
||||||
|
color = Color.Red,
|
||||||
|
modifier = Modifier.testTag("book_error")
|
||||||
|
)
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = onRefresh,
|
||||||
|
modifier = Modifier.testTag("book_refresh_button")
|
||||||
|
) {
|
||||||
|
Text("Обновить")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
|
||||||
|
// Кнопки: Забронировать и Назад
|
||||||
|
if (!uiState.isError && placesForDate.isNotEmpty()) {
|
||||||
|
Button(
|
||||||
|
onClick = onBook,
|
||||||
|
enabled = uiState.selectedPlace != null, // активна только при выбранном месте
|
||||||
|
modifier = Modifier.fillMaxWidth().testTag("book_book_button")
|
||||||
|
) { Text("Забронировать") }
|
||||||
|
}
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = onBack,
|
||||||
|
modifier = Modifier.fillMaxWidth().padding(top = 8.dp).testTag("book_back_button")
|
||||||
|
) {
|
||||||
|
Text("Назад")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Модель состояния интерфейса
|
||||||
|
data class BookingUiState(
|
||||||
|
val dates: List<LocalDate> = emptyList(), // список доступных дат
|
||||||
|
val places: Map<LocalDate, List<String>> = emptyMap(), // места по датам
|
||||||
|
val selectedDate: LocalDate? = null, // выбранная дата
|
||||||
|
val selectedPlace: String? = null, // выбранное место
|
||||||
|
val isError: Boolean = false, // флаг ошибки
|
||||||
|
val errorMessage: String? = null // сообщение об ошибке
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun BookScreen(
|
||||||
|
onBack: () -> Unit, // callback при возврате назад
|
||||||
|
onBookingSuccess: () -> Unit // callback при успешном бронировании
|
||||||
|
) {
|
||||||
|
val viewModel: BookingViewModel = viewModel()
|
||||||
|
val uiState by viewModel.uiState.collectAsState()
|
||||||
|
|
||||||
|
BookingScreen(
|
||||||
|
uiState = uiState,
|
||||||
|
onSelectDate = { date -> viewModel.selectDate(date) },
|
||||||
|
onSelectPlace = { place -> viewModel.selectPlace(place) },
|
||||||
|
onBook = {
|
||||||
|
viewModel.bookPlace()
|
||||||
|
onBookingSuccess()
|
||||||
|
},
|
||||||
|
onBack = onBack,
|
||||||
|
onRefresh = { viewModel.refresh() }
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package ru.myitschool.work.ui.screen.book
|
||||||
|
|
||||||
|
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.launch
|
||||||
|
import java.time.LocalDate
|
||||||
|
|
||||||
|
class BookingViewModel : ViewModel() {
|
||||||
|
|
||||||
|
private val _uiState = MutableStateFlow(BookingUiState())
|
||||||
|
val uiState: StateFlow<BookingUiState> = _uiState.asStateFlow()
|
||||||
|
|
||||||
|
init {
|
||||||
|
loadBookingData()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadBookingData() {
|
||||||
|
viewModelScope.launch {
|
||||||
|
try {
|
||||||
|
// Временные mock данные
|
||||||
|
val mockDates = listOf(
|
||||||
|
LocalDate.now().plusDays(1),
|
||||||
|
LocalDate.now().plusDays(2),
|
||||||
|
LocalDate.now().plusDays(3)
|
||||||
|
)
|
||||||
|
|
||||||
|
val mockPlaces = mapOf(
|
||||||
|
mockDates[0] to listOf("Место 1", "Место 2", "Место 3"),
|
||||||
|
mockDates[1] to listOf("Место 1", "Место 2"),
|
||||||
|
mockDates[2] to listOf("Место 1")
|
||||||
|
)
|
||||||
|
|
||||||
|
val sortedDates = mockDates.sorted()
|
||||||
|
val availableDates = sortedDates.filter { mockPlaces[it]?.isNotEmpty() == true }
|
||||||
|
val defaultDate = availableDates.firstOrNull()
|
||||||
|
|
||||||
|
_uiState.value = _uiState.value.copy(
|
||||||
|
dates = sortedDates,
|
||||||
|
places = mockPlaces,
|
||||||
|
selectedDate = defaultDate,
|
||||||
|
selectedPlace = null,
|
||||||
|
isError = false,
|
||||||
|
errorMessage = null
|
||||||
|
)
|
||||||
|
|
||||||
|
} catch (e: Exception) {
|
||||||
|
_uiState.value = _uiState.value.copy(
|
||||||
|
isError = true,
|
||||||
|
errorMessage = "Ошибка загрузки данных"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun selectDate(date: LocalDate) {
|
||||||
|
_uiState.value = _uiState.value.copy(
|
||||||
|
selectedDate = date,
|
||||||
|
selectedPlace = null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun selectPlace(place: String) {
|
||||||
|
_uiState.value = _uiState.value.copy(
|
||||||
|
selectedPlace = place
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bookPlace() {
|
||||||
|
viewModelScope.launch {
|
||||||
|
try {
|
||||||
|
//вызов API для бронирования
|
||||||
|
} catch (e: Exception) {
|
||||||
|
_uiState.value = _uiState.value.copy(
|
||||||
|
isError = true,
|
||||||
|
errorMessage = "Ошибка бронирования"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun refresh() {
|
||||||
|
loadBookingData()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,17 +1,207 @@
|
|||||||
package ru.myitschool.work.ui.screen.main
|
package ru.myitschool.work.ui.screen.main
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.material3.*
|
||||||
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.*
|
||||||
|
import ru.myitschool.work.ui.nav.BookScreenDestination
|
||||||
|
|
||||||
|
// Модель данных для бронирования
|
||||||
|
data class BookingItem(
|
||||||
|
val date: String, // Формат "dd.MM.yyyy"
|
||||||
|
val place: String,
|
||||||
|
val id: Int
|
||||||
|
)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MainScreen(navController: NavController) {
|
fun MainScreen(
|
||||||
Box(
|
navController: NavController,
|
||||||
contentAlignment = Alignment.Center
|
onNavigateToBooking: () -> Unit
|
||||||
) {
|
) {
|
||||||
Text(text = "Hello")
|
// Состояния
|
||||||
|
var userName by remember { mutableStateOf("Иван Иванов") }
|
||||||
|
var isLoading by remember { mutableStateOf(false) }
|
||||||
|
var errorMessage by remember { mutableStateOf("") }
|
||||||
|
var bookingItems by remember { mutableStateOf(emptyList<BookingItem>()) }
|
||||||
|
var hasError by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
// Для корутин
|
||||||
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
// Функция загрузки данных
|
||||||
|
fun loadData() {
|
||||||
|
isLoading = true
|
||||||
|
hasError = false
|
||||||
|
|
||||||
|
coroutineScope.launch {
|
||||||
|
kotlinx.coroutines.delay(1000) // Имитация задержки
|
||||||
|
|
||||||
|
// Имитация ответа от сервера
|
||||||
|
val response = listOf(
|
||||||
|
BookingItem("20.12.2023", "Конференц-зал А", 1),
|
||||||
|
BookingItem("15.12.2023", "Переговорная Б", 2),
|
||||||
|
BookingItem("25.12.2023", "Спортзал", 3)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Сортировка по дате (увеличение)
|
||||||
|
bookingItems = response.sortedBy {
|
||||||
|
SimpleDateFormat("dd.MM.yyyy", Locale.getDefault()).parse(it.date)
|
||||||
|
}
|
||||||
|
|
||||||
|
isLoading = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Первая загрузка при открытии экрана
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
loadData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если ошибка - показываем только ошибку и кнопку обновления
|
||||||
|
if (hasError) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.Center
|
||||||
|
) {
|
||||||
|
// Текстовое поле с ошибкой (main_error)
|
||||||
|
Text(
|
||||||
|
text = errorMessage,
|
||||||
|
color = MaterialTheme.colorScheme.error
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
// Кнопка обновления (main_refresh_button)
|
||||||
|
Button(onClick = { loadData() }) {
|
||||||
|
Text("Обновить")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Нормальное состояние
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(16.dp)
|
||||||
|
) {
|
||||||
|
// Верхняя строка
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
// Фото пользователя (main_photo)
|
||||||
|
Image(
|
||||||
|
painter = painterResource(id = android.R.drawable.ic_menu_gallery),
|
||||||
|
contentDescription = "Фото",
|
||||||
|
modifier = Modifier.size(64.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.width(16.dp))
|
||||||
|
|
||||||
|
// Имя пользователя (main_name)
|
||||||
|
Text(
|
||||||
|
text = userName,
|
||||||
|
style = MaterialTheme.typography.titleLarge,
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
color = MaterialTheme.colorScheme.onSurface
|
||||||
|
)
|
||||||
|
|
||||||
|
// Кнопка выхода (main_logout_button)
|
||||||
|
Button(onClick = {
|
||||||
|
// Очистка данных и переход на авторизацию
|
||||||
|
userName = ""
|
||||||
|
bookingItems = emptyList()
|
||||||
|
navController.navigate("auth") { popUpTo(0) }
|
||||||
|
}) {
|
||||||
|
Text("Выход")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
// Кнопки действий
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
|
) {
|
||||||
|
// Кнопка обновления (main_refresh_button)
|
||||||
|
Button(
|
||||||
|
onClick = { loadData() },
|
||||||
|
enabled = !isLoading
|
||||||
|
) {
|
||||||
|
if (isLoading) {
|
||||||
|
CircularProgressIndicator(
|
||||||
|
modifier = Modifier.size(16.dp),
|
||||||
|
color = MaterialTheme.colorScheme.onPrimary
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Text("Обновить")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = { navController.navigate(BookScreenDestination) }
|
||||||
|
) {
|
||||||
|
Text("Перейти к бронированию")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
// Список бронирований
|
||||||
|
if (bookingItems.isNotEmpty()) {
|
||||||
|
LazyColumn(modifier = Modifier.weight(1f)) {
|
||||||
|
items(bookingItems) { item ->
|
||||||
|
// Элемент списка (main_book_pos_{index})
|
||||||
|
Card(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 4.dp),
|
||||||
|
colors = CardDefaults.cardColors(
|
||||||
|
containerColor = MaterialTheme.colorScheme.surfaceVariant
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Column(modifier = Modifier.padding(16.dp)) {
|
||||||
|
// Дата бронирования (main_item_date)
|
||||||
|
Text(
|
||||||
|
text = "Дата: ${item.date}",
|
||||||
|
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(4.dp))
|
||||||
|
|
||||||
|
// Место бронирования (main_item_place)
|
||||||
|
Text(
|
||||||
|
text = "Место: ${item.place}",
|
||||||
|
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "Нет бронирований",
|
||||||
|
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user