package contacts.presentation import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Search import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.compose.ui.res.stringResource import contacts.data.remote.api.ContactDto import core.presentation.components.AppAvatar import core.presentation.theme.SoftSquareShape import ru.knot.messager.R @OptIn(ExperimentalMaterial3Api::class) @Composable fun ContactListScreen( contacts: List, isLoading: Boolean = false, onContactClick: (String) -> Unit, onSearchChange: (String) -> Unit ) { var searchQuery by remember { mutableStateOf("") } var selectedTab by remember { mutableIntStateOf(0) } val tabs = listOf( stringResource(R.string.all), stringResource(R.string.online_tab) ) Scaffold( topBar = { Column { TopAppBar( title = { Text(stringResource(R.string.contacts_title)) }, colors = TopAppBarDefaults.topAppBarColors( containerColor = MaterialTheme.colorScheme.primaryContainer ) ) TabRow(selectedTabIndex = selectedTab) { tabs.forEachIndexed { index, title -> Tab( selected = selectedTab == index, onClick = { selectedTab = index }, text = { Text(title) } ) } } } } ) { paddingValues -> Column( modifier = Modifier .fillMaxSize() .padding(paddingValues) ) { // Поисковая строка OutlinedTextField( value = searchQuery, onValueChange = { searchQuery = it onSearchChange(it) }, modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp, vertical = 8.dp), placeholder = { Text(stringResource(R.string.search_hint)) }, leadingIcon = { Icon(Icons.Default.Search, contentDescription = null) }, shape = SoftSquareShape ) if (isLoading) { Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { CircularProgressIndicator() } } else { val filteredContacts = contacts.filter { if (selectedTab == 1) it.isOnline else true } LazyColumn(modifier = Modifier.fillMaxSize()) { items(filteredContacts) { contact -> ContactItem(contact = contact, onClick = { onContactClick(contact.id) }) } } } } } } @Composable fun ContactItem(contact: ContactDto, onClick: () -> Unit) { Row( modifier = Modifier .fillMaxWidth() .clickable(onClick = onClick) .padding(16.dp, 8.dp), verticalAlignment = Alignment.CenterVertically ) { AppAvatar( url = contact.avatarUrl, name = contact.username, size = 56.dp ) Spacer(modifier = Modifier.width(16.dp)) Column(modifier = Modifier.weight(1f)) { Text( text = contact.displayName ?: contact.username, style = MaterialTheme.typography.titleMedium, color = MaterialTheme.colorScheme.onSurface ) val statusText = if (contact.isOnline) { stringResource(R.string.online) } else { stringResource(R.string.last_seen, contact.lastSeen ?: stringResource(R.string.last_seen_recently)) } Text( text = statusText, style = MaterialTheme.typography.bodySmall, color = if (contact.isOnline) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant ) } } }