fix: fix main screen

This commit is contained in:
2025-12-11 22:33:57 +03:00
parent 0a5803765e
commit e5df83f4e3

View File

@@ -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/<CODE>/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/<CODE>/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(
)
}
}
}
}
data class Booking(
val date: String,
val place: String
)