package agzam.vyatsu.ui.groups import agzam.vyatsu.domain.model.Group import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets 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.layout.systemBars import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Clear import androidx.compose.material.icons.filled.Refresh import androidx.compose.material.icons.filled.Search import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.SearchBar import androidx.compose.material3.SearchBarDefaults import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp /** * Страница выбора группы * @author Agzam */ @OptIn(ExperimentalMaterial3Api::class) @Composable fun GroupPickerScreen(viewModel: GroupPickerViewModel, onGroupPicked: (Group) -> Unit) { val state by viewModel.uiState.collectAsState() var isSearchActive by remember { mutableStateOf(false) } Scaffold { innerPadding -> Column( Modifier .fillMaxSize() .windowInsetsPadding(WindowInsets.systemBars) .padding(innerPadding) .padding(horizontal = 16.dp, vertical = 8.dp) ) { if (!isSearchActive) { Row( Modifier .fillMaxWidth() .padding(bottom = 8.dp), verticalAlignment = Alignment.CenterVertically ) { Text( text = "Выберите группу", style = MaterialTheme.typography.headlineSmall, modifier = Modifier.weight(1f) ) IconButton(onClick = { viewModel.refresh() }) { Icon(Icons.Default.Refresh, contentDescription = "Обновить") } } } if (state.isLoading && state.groups.isEmpty()) { Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) { CircularProgressIndicator() } return@Column } if (state.error != null && state.groups.isEmpty()) { Column(Modifier.fillMaxWidth()) { Text(state.error.orEmpty(), style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.error) TextButton(onClick = { viewModel.retry() }) { Text("Повторить") } } return@Column } SearchBar( modifier = Modifier.fillMaxWidth(), expanded = isSearchActive, onExpandedChange = { isSearchActive = it }, inputField = { SearchBarDefaults.InputField( query = state.searchQuery, onQueryChange = { viewModel.search(it) }, onSearch = { isSearchActive = false }, expanded = isSearchActive, onExpandedChange = { isSearchActive = it }, placeholder = { Text("Поиск группы") }, leadingIcon = { Icon(Icons.Default.Search, contentDescription = null) }, trailingIcon = { if (isSearchActive && state.searchQuery.isNotEmpty()) { IconButton(onClick = { viewModel.search("") }) { Icon(Icons.Default.Clear, contentDescription = "Очистить") } } } ) } ) { GroupList( groups = state.filteredGroups, onPick = { group -> isSearchActive = false onGroupPicked(group) } ) } if (!isSearchActive) { Spacer(modifier = Modifier.height(8.dp)) GroupList(state.filteredGroups, onGroupPicked) } } } } @Composable private fun GroupList(groups: List, onPick: (Group) -> Unit) { LazyColumn(modifier = Modifier.fillMaxSize()) { items(groups) { group -> Column(modifier = Modifier.fillMaxWidth() .clickable { onPick(group) }) { Box( modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 8.dp).padding(horizontal = 16.dp), contentAlignment = Alignment.CenterStart ) { Text(group.name, style = MaterialTheme.typography.bodyMedium) // XXX: стоит ли добавлять факультет или это засорит интерфейс // Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.Bottom) { // if (group.faculty.isNotEmpty()) Text(text = group.faculty + " · ", color = MaterialTheme.colorScheme.onSurfaceVariant) // } } } HorizontalDivider(thickness = 1.dp, color = MaterialTheme.colorScheme.outlineVariant) } } }