temporary changes. Will merge with the other branch.

This commit is contained in:
ankitsaraf 2025-12-21 14:44:36 +05:30
parent 80cc72bb9d
commit 4d7e8e3daf
15 changed files with 2388 additions and 2083 deletions

View File

@ -1 +0,0 @@
LivingAi_Lg

View File

@ -27,6 +27,7 @@ class UserNotFoundException(
class AuthApiClient(private val context: Context) {
private val route = "http://10.0.2.2:3000/"
private val tokenManager = TokenManager(context)
val client = HttpClient(CIO) {
@ -64,7 +65,7 @@ class AuthApiClient(private val context: Context) {
android.util.Log.d("AuthApiClient", "refreshTokens: Calling /auth/refresh endpoint")
try {
val response: RefreshResponse = client.post("http://10.0.2.2:3000/auth/refresh") {
val response: RefreshResponse = client.post("${route}auth/refresh") {
markAsRefreshTokenRequest()
contentType(ContentType.Application.Json)
setBody(RefreshRequest(refreshToken))
@ -84,7 +85,7 @@ class AuthApiClient(private val context: Context) {
}
defaultRequest {
url("http://10.0.2.2:3000/")
url(route)
}
}

View File

@ -22,10 +22,10 @@ import com.example.livingai_lg.ui.models.AnimalType
@Composable
fun AnimalTypeSelector(
animalTypes: List<AnimalType>,
selectedAnimalType: MutableState<String?>,
selectedAnimalType: String?,
onAnimalTypeSelected: (String) -> Unit
) {
val selectedAnimalType: String = selectedAnimalType.value ?: ""
val selectedAnimalType: String = selectedAnimalType ?: ""
LazyRow(
modifier = Modifier

View File

@ -13,6 +13,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
@ -61,7 +62,7 @@ fun BottomNavigationBar(
@Composable
fun BottomNavItem(
label: String,
iconRes: Int,
iconRes: Any,
selected: Boolean,
onClick: () -> Unit = {}
) {
@ -77,12 +78,21 @@ fun BottomNavItem(
interactionSource = remember { MutableInteractionSource() },
onClick = onClick)
) {
Icon(
painter = painterResource(iconRes),
contentDescription = label,
tint = color,
modifier = Modifier.size(24.dp)
)
if(iconRes is Int) {
Icon(
painter = painterResource(iconRes),
contentDescription = label,
tint = color,
modifier = Modifier.size(24.dp)
)
} else if(iconRes is ImageVector) {
Icon(
imageVector = iconRes,
contentDescription = label,
tint = color,
modifier = Modifier.size(24.dp)
)
}
Text(
text = label,
fontSize = 12.sp,

View File

@ -31,6 +31,7 @@ fun DropdownInput(
onExpandedChange: (Boolean) -> Unit,
onSelect: (String) -> Unit,
placeholder: String = "Select", // NEW - custom placeholder
textColor: Color = Color.Black,
modifier: Modifier = Modifier // NEW - allows width control
) {
Column(
@ -38,17 +39,17 @@ fun DropdownInput(
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
// Optional label
if (label != null) {
// if (label != null) {
Text(
text = label,
text = label?:" ",
fontSize = AppTypography.Body,
fontWeight = FontWeight.Medium,
color = FarmTextDark
)
} else {
// Reserve label space so layout doesnt shift
Spacer(modifier = Modifier.height(20.dp)) // ← same height as label text line
}
// } else {
// // Reserve label space so layout doesnt shift
// Spacer(modifier = Modifier.height(20.dp)) // ← same height as label text line
// }
ExposedDropdownMenuBox(
expanded = expanded,
@ -82,7 +83,7 @@ fun DropdownInput(
Text(
text = selected.ifEmpty { placeholder },
fontSize = AppTypography.Body,
color = if (selected.isEmpty()) Color(0xFF99A1AF) else FarmTextDark
color = if (selected.isEmpty()) Color(0xFF99A1AF) else textColor
)
Icon(

View File

@ -18,13 +18,15 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.example.livingai_lg.ui.models.FiltersState
import com.example.livingai_lg.ui.screens.FilterScreen
@Composable
fun FilterOverlay(
visible: Boolean,
appliedFilters: FiltersState,
onDismiss: () -> Unit,
onSubmitClick: () -> Unit = {},
onSubmitClick: (filters: FiltersState) -> Unit = {},
) {
BackHandler(enabled = visible) { onDismiss() }
@ -62,10 +64,11 @@ fun FilterOverlay(
.align(Alignment.CenterEnd)
) {
FilterScreen(
appliedFilters,
onBackClick = onDismiss,
onCancelClick = onDismiss,
onSubmitClick = {
onSubmitClick()
onSubmitClick = { filters ->
onSubmitClick(filters)
onDismiss()
}
)

View File

@ -27,6 +27,7 @@ fun RangeFilter(
max: Int,
valueFrom: Int,
valueTo: Int,
modified: Boolean = false,
onValueChange: (from: Int, to: Int) -> Unit,
showSlider: Boolean = true,
valueFormatter: (Int) -> String = { it.toString() }
@ -75,6 +76,7 @@ fun RangeFilter(
RangePill(
modifier = Modifier.weight(1f),
value = fromValue,
modified = modified,
onValueChange = { newFrom ->
val safeFrom = newFrom.coerceIn(min, toValue)
fromValue = safeFrom
@ -88,6 +90,7 @@ fun RangeFilter(
RangePill(
modifier = Modifier.weight(1f),
value = toValue,
modified = modified,
onValueChange = { newTo ->
val safeTo = newTo.coerceIn(fromValue, max)
toValue = safeTo
@ -104,6 +107,7 @@ fun RangeFilter(
private fun RangePill(
modifier: Modifier = Modifier,
value: Int,
modified: Boolean = false,
onValueChange: (Int) -> Unit,
formatter: (Int) -> String
) {
@ -119,6 +123,7 @@ private fun RangePill(
.padding(horizontal = 8.dp),
contentAlignment = Alignment.Center
) {
var modified = modified;
BasicTextField(
value = text,
onValueChange = { input ->
@ -129,7 +134,7 @@ private fun RangePill(
singleLine = true,
textStyle = TextStyle(
fontSize = 14.sp,
color = Color(0xFF99A1AF)
color = if(modified) Color.Black else Color(0xFF99A1AF)
),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
)

View File

@ -0,0 +1,80 @@
package com.example.livingai_lg.ui.components
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.background
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.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@Composable
fun WishlistNameOverlay(
onSave: (String) -> Unit,
onDismiss: () -> Unit
) {
var name by remember { mutableStateOf("") }
AnimatedVisibility(
visible = true,
enter = slideInVertically { -it },
exit = slideOutVertically { -it }
) {
Box(
Modifier
.fillMaxWidth()
.background(Color.White)
.padding(16.dp)
) {
Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
Text(
text = "Save Filters",
fontSize = 18.sp,
fontWeight = FontWeight.SemiBold
)
OutlinedTextField(
value = name,
onValueChange = { name = it },
placeholder = { Text("Wishlist name") },
singleLine = true
)
Row(
horizontalArrangement = Arrangement.End,
modifier = Modifier.fillMaxWidth()
) {
TextButton(onClick = onDismiss) {
Text("Cancel")
}
Button(
onClick = {
if (name.isNotBlank()) {
onSave(name)
}
}
) {
Text("Save")
}
}
}
}
}
}

View File

@ -1,11 +1,14 @@
package com.example.livingai_lg.ui.models
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Build
import androidx.compose.material.icons.outlined.Home
import com.example.livingai_lg.R
import com.example.livingai_lg.ui.navigation.AppScreen
data class BottomNavItemData(
val label: String,
val iconRes: Int,
val iconRes: Any,
val route: String,
)
@ -15,11 +18,11 @@ val mainBottomNavItems = listOf(
// TODO:
BottomNavItemData("Chats", R.drawable.ic_chat, AppScreen.CHATS),
BottomNavItemData("Services", R.drawable.ic_config, AppScreen.CREATE_PROFILE),
BottomNavItemData("Mandi", R.drawable.ic_market, AppScreen.CREATE_PROFILE)
BottomNavItemData("Mandi", R.drawable.ic_shop2, AppScreen.CREATE_PROFILE)
)
val chatBottomNavItems = listOf(
BottomNavItemData("Contacts", R.drawable.ic_home ,"home"),
BottomNavItemData("Calls", R.drawable.ic_tag, "sell"),
BottomNavItemData("Chats", R.drawable.ic_chat, "chats"),
BottomNavItemData("Contacts", R.drawable.ic_home ,AppScreen.CONTACTS),
BottomNavItemData("Calls", R.drawable.ic_tag, AppScreen.CALLS),
BottomNavItemData("Chats", R.drawable.ic_chat, AppScreen.CHATS),
)

View File

@ -0,0 +1,42 @@
package com.example.livingai_lg.ui.models
data class TextFilter(
val value: String = "",
val filterSet: Boolean = false
)
data class RangeFilterState(
val min: Int,
val max: Int,
val filterSet: Boolean = false
)
data class FiltersState(
val animal: TextFilter = TextFilter(),
val breed: TextFilter = TextFilter(),
val distance: TextFilter = TextFilter(),
val gender: TextFilter = TextFilter(),
val price: RangeFilterState = RangeFilterState(0, 90_000),
val age: RangeFilterState = RangeFilterState(0, 20),
val weight: RangeFilterState = RangeFilterState(0, 9_000),
val milkYield: RangeFilterState = RangeFilterState(0, 900),
val pregnancyStatuses: Set<String> = emptySet(),
val calving: RangeFilterState = RangeFilterState(0, 10)
)
fun FiltersState.isDefault(): Boolean {
return animal.filterSet.not() &&
breed.filterSet.not() &&
distance.filterSet.not() &&
gender.filterSet.not() &&
price.filterSet.not() &&
age.filterSet.not() &&
weight.filterSet.not() &&
milkYield.filterSet.not() &&
pregnancyStatuses.isEmpty() &&
calving.filterSet.not()
}

View File

@ -0,0 +1,32 @@
package com.example.livingai_lg.ui.models
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import java.util.UUID
data class WishlistEntry(
val id: String = UUID.randomUUID().toString(),
val name: String,
val filters: FiltersState,
val createdAt: Long = System.currentTimeMillis()
)
object WishlistStore {
private val _wishlist =
MutableStateFlow<List<WishlistEntry>>(emptyList())
val wishlist: StateFlow<List<WishlistEntry>> = _wishlist
fun add(entry: WishlistEntry) {
_wishlist.value = _wishlist.value + entry
}
fun remove(id: String) {
_wishlist.value = _wishlist.value.filterNot { it.id == id }
}
fun clear() {
_wishlist.value = emptyList()
}
}

View File

@ -19,6 +19,7 @@ import androidx.compose.material.icons.automirrored.filled.ArrowForwardIos
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.ArrowForwardIos
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.FavoriteBorder
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
@ -30,42 +31,47 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.livingai_lg.ui.components.DropdownInput
import com.example.livingai_lg.ui.components.RangeFilter
import com.example.livingai_lg.ui.components.WishlistNameOverlay
import com.example.livingai_lg.ui.models.FiltersState
import com.example.livingai_lg.ui.models.RangeFilterState
import com.example.livingai_lg.ui.models.TextFilter
import com.example.livingai_lg.ui.models.WishlistEntry
import com.example.livingai_lg.ui.models.WishlistStore
import com.example.livingai_lg.ui.models.isDefault
import com.example.livingai_lg.ui.theme.AppTypography
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun FilterScreen(
appliedFilters: FiltersState,
wishlistEditMode: Boolean = false,
onSubmitClick: (FiltersState) -> Unit,
onBackClick: () -> Unit = {},
onSubmitClick: () -> Unit = {},
onCancelClick: () -> Unit = {},
) {
var selectedAnimal by remember { mutableStateOf("") }
var selectedBreed by remember { mutableStateOf("") }
var selectedDistance by remember { mutableStateOf("") }
var selectedGender by remember { mutableStateOf("") }
var filters by remember {
mutableStateOf(appliedFilters)
}
var showWishlistOverlay by remember { mutableStateOf(false) }
var selectedAnimal =filters.animal
var selectedBreed = filters.breed
var selectedDistance = filters.distance
var selectedGender = filters.gender
var animalExpanded by remember { mutableStateOf(false) }
var breedExpanded by remember { mutableStateOf(false) }
var distanceExpanded by remember { mutableStateOf(false) }
var genderExpanded by remember { mutableStateOf(false) }
var priceFrom by remember { mutableStateOf("0") }
var priceTo by remember { mutableStateOf("90,000") }
var priceSliderValue by remember { mutableFloatStateOf(0f) }
var price =filters.price
var age = filters.age
var weight = filters.weight
var milkYield = filters.milkYield
var calving = filters.calving
var ageFrom by remember { mutableStateOf("1") }
var ageTo by remember { mutableStateOf("20") }
var selectedPregnancyStatus = filters.pregnancyStatuses
var selectedPregnancyStatus by remember { mutableStateOf(setOf<String>()) }
var weightFrom by remember { mutableStateOf("0") }
var weightTo by remember { mutableStateOf("9000") }
var milkYieldFrom by remember { mutableStateOf("0") }
var milkYieldTo by remember { mutableStateOf("900") }
var calvingFrom by remember { mutableStateOf(0) }
var calvingTo by remember { mutableStateOf(10) }
var calvingFromExpanded by remember { mutableStateOf(false) }
var calvingToExpanded by remember { mutableStateOf(false) }
@ -73,7 +79,7 @@ fun FilterScreen(
val maxCalving = 10
val calvingFromOptions = (0..maxCalving).map { it.toString() }
val calvingToOptions = (calvingFrom..maxCalving).map { it.toString() }
val calvingToOptions = (calving.min..maxCalving).map { it.toString() }
Column(
modifier = Modifier
@ -109,6 +115,21 @@ fun FilterScreen(
fontWeight = FontWeight.Normal,
color = Color.Black
)
if(!wishlistEditMode){
IconButton(
onClick = {
if (!filters.isDefault()) {
showWishlistOverlay = true
}
}
) {
Icon(
imageVector = Icons.Default.FavoriteBorder,
contentDescription = "Add to Wishlist"
)
}
}
}
}
}
@ -128,15 +149,21 @@ fun FilterScreen(
) {
DropdownInput(
label = "Animal",
selected = selectedAnimal,
selected = if (selectedAnimal.filterSet) selectedAnimal.value else "",
options = listOf("Cow", "Buffalo", "Goat", "Sheep"),
expanded = animalExpanded,
onExpandedChange = { animalExpanded = it },
onSelect = { item ->
selectedAnimal = item
filters = filters.copy(
animal = TextFilter(
value = item,
filterSet = true
)
)
animalExpanded = false
},
placeholder = "Select Animal", // <--- half width
textColor = if (selectedAnimal.filterSet) Color.Black else Color.Gray
)
}
@ -146,15 +173,21 @@ fun FilterScreen(
) {
DropdownInput(
label = "Breed",
selected = selectedBreed,
selected = if (selectedBreed.filterSet) selectedBreed.value else "",
options = listOf("Holstein", "Jersey", "Gir", "Sahiwal"),
expanded = breedExpanded,
onExpandedChange = { breedExpanded = it },
onSelect = { item ->
selectedBreed = item
filters = filters.copy(
breed = TextFilter(
value = item,
filterSet = true
)
)
breedExpanded = false
},
placeholder = "Select Breed", // <--- half width
textColor = if (selectedAnimal.filterSet) Color.Black else Color.Gray
)
}
@ -166,14 +199,21 @@ fun FilterScreen(
) {
RangeFilter(
modifier = Modifier.fillMaxWidth(), // 👈 important
label = "Price",
min = 0,
max = 90_000,
valueFrom = priceFrom.toInt(),
valueTo = priceTo.replace(",", "").toInt(),
valueFrom = price.min,
valueTo = price.max,
modified = price.filterSet,
onValueChange = { from, to ->
priceFrom = from.toString()
priceTo = to.toString()
filters = filters.copy(
price = RangeFilterState(
min = from,
max = to,
filterSet = true
)
)
}
)
}
@ -183,18 +223,26 @@ fun FilterScreen(
) {
RangeFilter(
modifier = Modifier.fillMaxWidth(),
label = "Age",
modifier = Modifier.fillMaxWidth(), // 👈 important
label = "Age (years)",
min = 0,
max = 20,
valueFrom = ageFrom.toInt(),
valueTo = ageTo.replace(",", "").toInt(),
valueFrom = age.min,
valueTo = age.max,
showSlider = false,
modified = age.filterSet,
onValueChange = { from, to ->
ageFrom = from.toString()
ageTo = to.toString()
filters = filters.copy(
age = RangeFilterState(
min = from,
max = to,
filterSet = true
)
)
}
)
}
@ -206,15 +254,21 @@ fun FilterScreen(
) {
DropdownInput(
label = "Distance",
selected = selectedDistance,
selected = if (selectedDistance.filterSet) selectedDistance.value else "",
options = listOf("0-5 km", "5-10 km", "10-20 km", "20+ km"),
expanded = distanceExpanded,
onExpandedChange = { distanceExpanded = it },
onSelect = { item ->
selectedDistance = item
filters = filters.copy(
distance = TextFilter(
value = item,
filterSet = true
)
)
distanceExpanded = false
},
placeholder = "Choose Distance", // <--- half width
textColor = if (selectedAnimal.filterSet) Color.Black else Color.Gray
)
}
@ -224,15 +278,21 @@ fun FilterScreen(
) {
DropdownInput(
label = "Gender",
selected = selectedGender,
selected = if (selectedGender.filterSet) selectedGender.value else "",
options = listOf("Male", "Female"),
expanded = genderExpanded,
onExpandedChange = { genderExpanded = it },
onSelect = { item ->
selectedGender = item
filters = filters.copy(
gender = TextFilter(
value = item,
filterSet = true
)
)
genderExpanded = false
},
placeholder = "Choose Gender", // <--- half width
textColor = if (selectedAnimal.filterSet) Color.Black else Color.Gray
)
}
@ -259,11 +319,13 @@ fun FilterScreen(
label = status,
isSelected = selectedPregnancyStatus.contains(status),
onClick = {
selectedPregnancyStatus = if (selectedPregnancyStatus.contains(status)) {
selectedPregnancyStatus - status
} else {
selectedPregnancyStatus + status
}
filters = filters.copy(
pregnancyStatuses =
if (filters.pregnancyStatuses.contains(status))
filters.pregnancyStatuses - status
else
filters.pregnancyStatuses + status
)
}
)
}
@ -276,14 +338,21 @@ fun FilterScreen(
) {
RangeFilter(
modifier = Modifier.fillMaxWidth(), // 👈 important
label = "Weight",
min = 0,
max = 9000,
valueFrom = weightFrom.toInt(),
valueTo = weightTo.replace(",", "").toInt(),
valueFrom = weight.min,
valueTo = weight.max,
modified = weight.filterSet,
onValueChange = { from, to ->
weightFrom = from.toString()
weightTo = to.toString()
filters = filters.copy(
weight = RangeFilterState(
min = from,
max = to,
filterSet = true
)
)
}
)
}
@ -292,16 +361,22 @@ fun FilterScreen(
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
RangeFilter(
modifier = Modifier.fillMaxWidth(),
modifier = Modifier.fillMaxWidth(), // 👈 important
label = "Milk Yield",
min = 0,
max = 900,
valueFrom = milkYieldFrom.toInt(),
valueTo = milkYieldTo.replace(",", "").toInt(),
showSlider = true,
valueFrom = milkYield.min,
valueTo = milkYield.max,
modified = milkYield.filterSet,
onValueChange = { from, to ->
milkYieldFrom = from.toString()
milkYieldTo = to.toString()
filters = filters.copy(
milkYield = RangeFilterState(
min = from,
max = to,
filterSet = true
)
)
}
)
}
@ -321,18 +396,21 @@ fun FilterScreen(
// FROM
DropdownInput(
label = "Calving Number",
selected = calvingFrom.toString(),
selected = calving.min.toString(),
options = calvingFromOptions,
expanded = calvingFromExpanded,
onExpandedChange = { calvingFromExpanded = it },
onSelect = { value ->
val newFrom = value.toInt()
calvingFrom = newFrom
val newTo = maxOf(calving.max, newFrom)
// 👇 enforce invariant
if (calvingTo < newFrom) {
calvingTo = newFrom
}
filters = filters.copy(
calving = RangeFilterState(
min = newFrom,
max = newTo,
filterSet = true
)
)
calvingFromExpanded = false
},
@ -348,12 +426,21 @@ fun FilterScreen(
// TO
DropdownInput(
selected = calvingTo.toString(),
selected = calving.max.toString(),
options = calvingToOptions, // 👈 constrained options
expanded = calvingToExpanded,
onExpandedChange = { calvingToExpanded = it },
onSelect = { value ->
calvingTo = value.toInt()
val newTo = value.toInt()
val newFrom = minOf(calving.min, newTo)
filters = filters.copy(
calving = RangeFilterState(
min = newFrom,
max = newTo,
filterSet = true
)
)
calvingToExpanded = false
},
placeholder = "To",
@ -372,7 +459,7 @@ fun FilterScreen(
) {
// Submit Button
Button(
onClick = onSubmitClick,
onClick = { onSubmitClick(filters) },
modifier = Modifier
.width(173.dp)
.height(50.dp),
@ -414,6 +501,20 @@ fun FilterScreen(
}
}
}
if (showWishlistOverlay) {
WishlistNameOverlay(
onDismiss = { showWishlistOverlay = false },
onSave = { name ->
WishlistStore.add(
WishlistEntry(
name = name,
filters = filters
)
)
showWishlistOverlay = false
}
)
}
}
@Composable
@ -438,7 +539,8 @@ fun PregnancyStatusChip(
.clickable(
indication = LocalIndication.current,
interactionSource = remember { MutableInteractionSource() },
onClick = onClick)
onClick = onClick
)
.padding(horizontal = 12.dp),
contentAlignment = Alignment.Center
) {

View File

@ -27,6 +27,8 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.livingai_lg.ui.layout.BottomNavScaffold
import com.example.livingai_lg.ui.models.chatBottomNavItems
data class CallRecord(
val id: String,
@ -101,34 +103,41 @@ fun CallsScreen(
.fillMaxSize()
.background(Color(0xFFFCFBF8))
) {
Column(
modifier = Modifier.fillMaxSize()
) {
CallsHeader(
onBackClick = onBackClick,
onCallClick = onCallClick,
onMenuClick = onMenuClick
)
BottomNavScaffold(
items = chatBottomNavItems,
currentItem = "Calls",
onBottomNavItemClick = onTabClick,
) { paddingValues ->
LazyColumn(
modifier = Modifier
.fillMaxWidth()
.weight(1f)
.padding(horizontal = 16.dp, vertical = 16.dp),
verticalArrangement = Arrangement.spacedBy(12.dp)
Column(
modifier = Modifier.fillMaxSize().padding(paddingValues)
) {
items(callHistory) { call ->
CallHistoryItem(
call = call,
onClick = { onCallItemClick(call.id) }
)
}
}
CallsHeader(
onBackClick = onBackClick,
onCallClick = onCallClick,
onMenuClick = onMenuClick
)
ContactsBottomNav(
currentTab = ContactsTab.CALLS,
onTabClick = onTabClick
)
LazyColumn(
modifier = Modifier
.fillMaxWidth()
.weight(1f)
.padding(horizontal = 16.dp, vertical = 16.dp),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
items(callHistory) { call ->
CallHistoryItem(
call = call,
onClick = { onCallItemClick(call.id) }
)
}
}
// ContactsBottomNav(
// currentTab = ContactsTab.CALLS,
// onTabClick = onTabClick
// )
}
}
}
}

View File

@ -27,6 +27,8 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.farmmarketplace.ui.screens.ContactsBottomNav
import com.example.farmmarketplace.ui.screens.ContactsTab
import com.example.livingai_lg.ui.layout.BottomNavScaffold
import com.example.livingai_lg.ui.models.chatBottomNavItems
data class ChatPreview(
val id: String,
@ -108,34 +110,40 @@ fun ChatsScreen(
.fillMaxSize()
.background(Color(0xFFFCFBF8))
) {
Column(
modifier = Modifier.fillMaxSize()
) {
ChatsHeader(
onBackClick = onBackClick,
onNewChatClick = onNewChatClick,
onMenuClick = onMenuClick
)
LazyColumn(
modifier = Modifier
.fillMaxWidth()
.weight(1f)
.padding(horizontal = 16.dp, vertical = 16.dp),
verticalArrangement = Arrangement.spacedBy(12.dp)
BottomNavScaffold(
items = chatBottomNavItems,
currentItem = "Chats",
onBottomNavItemClick = onTabClick,
) { paddingValues ->
Column(
modifier = Modifier.fillMaxSize().padding(paddingValues)
) {
items(chatList) { chat ->
ChatListItem(
chat = chat,
onClick = { onChatItemClick(chat.id) }
)
}
}
ChatsHeader(
onBackClick = onBackClick,
onNewChatClick = onNewChatClick,
onMenuClick = onMenuClick
)
ContactsBottomNav(
currentTab = ContactsTab.CHATS,
onTabClick = onTabClick
)
LazyColumn(
modifier = Modifier
.fillMaxWidth()
.weight(1f)
.padding(horizontal = 16.dp, vertical = 16.dp),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
items(chatList) { chat ->
ChatListItem(
chat = chat,
onClick = { onChatItemClick(chat.id) }
)
}
}
// ContactsBottomNav(
// currentTab = ContactsTab.CHATS,
// onTabClick = onTabClick
// )
}
}
}
}

View File

@ -34,6 +34,9 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.livingai_lg.ui.layout.BottomNavScaffold
import com.example.livingai_lg.ui.models.chatBottomNavItems
import com.example.livingai_lg.ui.models.mainBottomNavItems
import com.example.livingai_lg.ui.navigation.AppScreen
data class Contact(
@ -122,34 +125,41 @@ fun ContactsScreen(
.fillMaxSize()
.background(Color(0xFFFCFBF8))
) {
Column(
modifier = Modifier.fillMaxSize()
) {
ContactsHeader(
onBackClick = onBackClick,
onSearchClick = onSearchClick,
onMenuClick = onMenuClick
)
BottomNavScaffold(
items = chatBottomNavItems,
currentItem = "Contacts",
onBottomNavItemClick = onTabClick,
) { paddingValues ->
LazyColumn(
modifier = Modifier
.fillMaxWidth()
.weight(1f)
Column(
modifier = Modifier.fillMaxSize().padding(paddingValues)
) {
items(contacts) { contact ->
ContactItem(
contact = contact,
onContactClick = { onContactClick(contact.id) },
onCallClick = { onCallClick(contact.id) },
onMessageClick = { onMessageClick(contact.id) }
)
}
}
ContactsHeader(
onBackClick = onBackClick,
onSearchClick = onSearchClick,
onMenuClick = onMenuClick
)
ContactsBottomNav(
currentTab = ContactsTab.CONTACTS,
onTabClick = onTabClick
)
LazyColumn(
modifier = Modifier
.fillMaxWidth()
.weight(1f)
) {
items(contacts) { contact ->
ContactItem(
contact = contact,
onContactClick = { onContactClick(contact.id) },
onCallClick = { onCallClick(contact.id) },
onMessageClick = { onMessageClick(contact.id) }
)
}
}
// ContactsBottomNav(
// currentTab = ContactsTab.CONTACTS,
// onTabClick = onTabClick
// )
}
}
}
}