diff --git a/app/src/main/java/ru/myitschool/work/ui/screen/main/MainScreen.kt b/app/src/main/java/ru/myitschool/work/ui/screen/main/MainScreen.kt index 1cd5afd..7d4fd94 100644 --- a/app/src/main/java/ru/myitschool/work/ui/screen/main/MainScreen.kt +++ b/app/src/main/java/ru/myitschool/work/ui/screen/main/MainScreen.kt @@ -16,30 +16,45 @@ import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults +import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold 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.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController import coil3.compose.AsyncImage import ru.myitschool.work.R import ru.myitschool.work.core.TestIds -import ru.myitschool.work.ui.nav.MainScreenDestination import ru.myitschool.work.data.repo.AuthRepository import ru.myitschool.work.ui.nav.AuthScreenDestination +import ru.myitschool.work.ui.nav.BookScreenDestination + + +/* +По умолчанию скрытое текстовое поле с ошибкой (main_error). + +Требования к компонентам: + +В случае любой ошибки необходимо скрыть все элементы, кроме текстового поля с ошибкой и кнопки обновления данных. +Для получения данных необходимо использовать сетевой запрос /api//info. +При нажатии на кнопку для выхода, все сохранённые данные пользователя должны быть очищены, а приложение должно открыть экран авторизации. +При нажатии кнопки бронирования необходимо открыть экран бронирования. +При нажатии на кнопку обновления данных — необходимо повторно вызывать сетевой запрос для получения актуальных данных. +Список бронирований должен быть отсортирован в порядке увеличения даты (например, 5 января -> 6 января -> 9 января). + */ + @Composable fun MainScreen( @@ -48,19 +63,46 @@ fun MainScreen( ) { val state by viewModel.uiState.collectAsState() - /* - По умолчанию скрытое текстовое поле с ошибкой (main_error). + Column( + modifier = Modifier + .fillMaxSize() + .imePadding() + .padding(20.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Top + ) { + Button( + modifier = Modifier + .fillMaxWidth() + .testTag(TestIds.Main.REFRESH_BUTTON), + onClick = { /* обновить данные */ } + ) { + Text(stringResource(R.string.refresh)) + } - Требования к компонентам: + Spacer(modifier = Modifier.size(8.dp)) - В случае любой ошибки необходимо скрыть все элементы, кроме текстового поля с ошибкой и кнопки обновления данных. - Для получения данных необходимо использовать сетевой запрос /api//info. - При нажатии на кнопку для выхода, все сохранённые данные пользователя должны быть очищены, а приложение должно открыть экран авторизации. ГОТОВО - При нажатии кнопки бронирования необходимо открыть экран бронирования. - При нажатии на кнопку обновления данных — необходимо повторно вызывать сетевой запрос для получения актуальных данных. - Список бронирований должен быть отсортирован в порядке увеличения даты (например, 5 января -> 6 января -> 9 января). - */ + when (state) { + is MainState.Error -> { + Text( + text = (state as MainState.Error).message, + color = MaterialTheme.colorScheme.error, + textAlign = TextAlign.Center, + modifier = Modifier.fillMaxWidth() + ) + } + is MainState.Loading -> { + CircularProgressIndicator() + } + is MainState.Data -> { + MainContent(navController = navController) + } + } + } +} +@Composable +fun MainContent(navController: NavController) { val bookings = listOf( Booking(date = "2025-12-01", place = "Аудитория 1"), Booking(date = "2025-12-01", place = "Аудитория 2"), @@ -72,23 +114,8 @@ fun MainScreen( Booking(date = "2025-12-04", place = "Спортивный зал"), ) - LaunchedEffect(Unit) { - viewModel.actionFlow.collect { - navController.navigate(MainScreenDestination) - } - } - Column( - modifier = Modifier - .fillMaxSize() - .imePadding() - .padding( - start = 20.dp, - top = 20.dp, - end = 20.dp, - bottom = 0.dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Top + modifier = Modifier.fillMaxSize() ) { Row( modifier = Modifier.fillMaxWidth(), @@ -102,26 +129,20 @@ fun MainScreen( modifier = Modifier .size(60.dp) .clip(CircleShape) - .testTag(TestIds.Main.PROFILE_IMAGE) ) Spacer(modifier = Modifier.size(16.dp)) Text( text = "Иванов Иван Иванович", - style = MaterialTheme.typography.titleLarge, - modifier = Modifier - .testTag(TestIds.Main.PROFILE_NAME) + style = MaterialTheme.typography.titleLarge ) } Spacer(modifier = Modifier.size(8.dp)) Button( - modifier = Modifier - .fillMaxWidth() - .testTag(TestIds.Main.LOGOUT_BUTTON), + modifier = Modifier.fillMaxWidth(), colors = ButtonDefaults.buttonColors( - containerColor = MaterialTheme.colorScheme.error, - contentColor = MaterialTheme.colorScheme.onError + containerColor = MaterialTheme.colorScheme.error ), onClick = { AuthRepository.clearCode() @@ -134,35 +155,14 @@ fun MainScreen( Spacer(modifier = Modifier.size(8.dp)) Button( - modifier = Modifier - .fillMaxWidth() - .testTag(TestIds.Main.REFRESH_BUTTON), - colors = ButtonDefaults.buttonColors( - containerColor = MaterialTheme.colorScheme.primary, - contentColor = MaterialTheme.colorScheme.onPrimary - ), - onClick = { - }, - ) { - Text(stringResource(R.string.refresh)) - } - - Spacer(modifier = Modifier.size(8.dp)) - - Button( - modifier = Modifier - .fillMaxWidth() - .testTag(TestIds.Main.ADD_BUTTON), - colors = ButtonDefaults.buttonColors( - containerColor = Color(0xFF2E7D32), - contentColor = Color.White - ), - onClick = { - }, + modifier = Modifier.fillMaxWidth(), + onClick = { navController.navigate(BookScreenDestination) } ) { Text(stringResource(R.string.book_new)) } + Spacer(modifier = Modifier.size(8.dp)) + Scaffold( modifier = Modifier.fillMaxSize() ) { paddingValues -> @@ -189,11 +189,6 @@ fun MainScreen( } } -data class Booking( - val date: String, - val place: String -) - @Composable fun BookCard( date: String, @@ -201,16 +196,9 @@ fun BookCard( modifier: Modifier = Modifier ) { val formattedDate = remember(date) { - try { - val parts = date.split("-") - if (parts.size == 3) { - "${parts[2]}.${parts[1]}.${parts[0]}" - } else { - date - } - } catch (_: Exception) { - date - } + runCatching { + java.time.LocalDate.parse(date).format(java.time.format.DateTimeFormatter.ofPattern("dd.MM.yyyy")) + }.getOrElse { date } } Card( @@ -243,4 +231,9 @@ fun BookCard( ) } } -} \ No newline at end of file +} + +data class Booking( + val date: String, + val place: String +) \ No newline at end of file