Compare commits
No commits in common. "c5750e6b5ee7d12868cd6df502f41a2df78d6e5e" and "80cc72bb9d1cb3ea922efe4d9bca3726e2dfe475" have entirely different histories.
c5750e6b5e
...
80cc72bb9d
|
|
@ -0,0 +1 @@
|
|||
LivingAi_Lg
|
||||
|
|
@ -27,7 +27,6 @@ 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) {
|
||||
|
|
@ -65,7 +64,7 @@ class AuthApiClient(private val context: Context) {
|
|||
|
||||
android.util.Log.d("AuthApiClient", "refreshTokens: Calling /auth/refresh endpoint")
|
||||
try {
|
||||
val response: RefreshResponse = client.post("${route}auth/refresh") {
|
||||
val response: RefreshResponse = client.post("http://10.0.2.2:3000/auth/refresh") {
|
||||
markAsRefreshTokenRequest()
|
||||
contentType(ContentType.Application.Json)
|
||||
setBody(RefreshRequest(refreshToken))
|
||||
|
|
@ -85,7 +84,7 @@ class AuthApiClient(private val context: Context) {
|
|||
}
|
||||
|
||||
defaultRequest {
|
||||
url(route)
|
||||
url("http://10.0.2.2:3000/")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@ import com.example.livingai_lg.ui.models.AnimalType
|
|||
@Composable
|
||||
fun AnimalTypeSelector(
|
||||
animalTypes: List<AnimalType>,
|
||||
selectedAnimalType: String?,
|
||||
selectedAnimalType: MutableState<String?>,
|
||||
onAnimalTypeSelected: (String) -> Unit
|
||||
) {
|
||||
val selectedAnimalType: String = selectedAnimalType ?: ""
|
||||
val selectedAnimalType: String = selectedAnimalType.value ?: ""
|
||||
|
||||
LazyRow(
|
||||
modifier = Modifier
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ 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
|
||||
|
|
@ -62,7 +61,7 @@ fun BottomNavigationBar(
|
|||
@Composable
|
||||
fun BottomNavItem(
|
||||
label: String,
|
||||
iconRes: Any,
|
||||
iconRes: Int,
|
||||
selected: Boolean,
|
||||
onClick: () -> Unit = {}
|
||||
) {
|
||||
|
|
@ -78,21 +77,12 @@ fun BottomNavItem(
|
|||
interactionSource = remember { MutableInteractionSource() },
|
||||
onClick = onClick)
|
||||
) {
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ 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(
|
||||
|
|
@ -39,17 +38,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 doesn’t shift
|
||||
// Spacer(modifier = Modifier.height(20.dp)) // ← same height as label text line
|
||||
// }
|
||||
} else {
|
||||
// Reserve label space so layout doesn’t shift
|
||||
Spacer(modifier = Modifier.height(20.dp)) // ← same height as label text line
|
||||
}
|
||||
|
||||
ExposedDropdownMenuBox(
|
||||
expanded = expanded,
|
||||
|
|
@ -83,7 +82,7 @@ fun DropdownInput(
|
|||
Text(
|
||||
text = selected.ifEmpty { placeholder },
|
||||
fontSize = AppTypography.Body,
|
||||
color = if (selected.isEmpty()) Color(0xFF99A1AF) else textColor
|
||||
color = if (selected.isEmpty()) Color(0xFF99A1AF) else FarmTextDark
|
||||
)
|
||||
|
||||
Icon(
|
||||
|
|
|
|||
|
|
@ -18,15 +18,13 @@ 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: (filters: FiltersState) -> Unit = {},
|
||||
onSubmitClick: () -> Unit = {},
|
||||
) {
|
||||
BackHandler(enabled = visible) { onDismiss() }
|
||||
|
||||
|
|
@ -64,11 +62,10 @@ fun FilterOverlay(
|
|||
.align(Alignment.CenterEnd)
|
||||
) {
|
||||
FilterScreen(
|
||||
appliedFilters,
|
||||
onBackClick = onDismiss,
|
||||
onCancelClick = onDismiss,
|
||||
onSubmitClick = { filters ->
|
||||
onSubmitClick(filters)
|
||||
onSubmitClick = {
|
||||
onSubmitClick()
|
||||
onDismiss()
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ 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() }
|
||||
|
|
@ -76,7 +75,6 @@ fun RangeFilter(
|
|||
RangePill(
|
||||
modifier = Modifier.weight(1f),
|
||||
value = fromValue,
|
||||
modified = modified,
|
||||
onValueChange = { newFrom ->
|
||||
val safeFrom = newFrom.coerceIn(min, toValue)
|
||||
fromValue = safeFrom
|
||||
|
|
@ -90,7 +88,6 @@ fun RangeFilter(
|
|||
RangePill(
|
||||
modifier = Modifier.weight(1f),
|
||||
value = toValue,
|
||||
modified = modified,
|
||||
onValueChange = { newTo ->
|
||||
val safeTo = newTo.coerceIn(fromValue, max)
|
||||
toValue = safeTo
|
||||
|
|
@ -107,7 +104,6 @@ fun RangeFilter(
|
|||
private fun RangePill(
|
||||
modifier: Modifier = Modifier,
|
||||
value: Int,
|
||||
modified: Boolean = false,
|
||||
onValueChange: (Int) -> Unit,
|
||||
formatter: (Int) -> String
|
||||
) {
|
||||
|
|
@ -123,7 +119,6 @@ private fun RangePill(
|
|||
.padding(horizontal = 8.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
var modified = modified;
|
||||
BasicTextField(
|
||||
value = text,
|
||||
onValueChange = { input ->
|
||||
|
|
@ -134,7 +129,7 @@ private fun RangePill(
|
|||
singleLine = true,
|
||||
textStyle = TextStyle(
|
||||
fontSize = 14.sp,
|
||||
color = if(modified) Color.Black else Color(0xFF99A1AF)
|
||||
color = Color(0xFF99A1AF)
|
||||
),
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,80 +0,0 @@
|
|||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,11 @@
|
|||
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: Any,
|
||||
val iconRes: Int,
|
||||
val route: String,
|
||||
)
|
||||
|
||||
|
|
@ -18,11 +15,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_shop2, AppScreen.CREATE_PROFILE)
|
||||
BottomNavItemData("Mandi", R.drawable.ic_market, AppScreen.CREATE_PROFILE)
|
||||
)
|
||||
|
||||
val chatBottomNavItems = listOf(
|
||||
BottomNavItemData("Contacts", R.drawable.ic_home ,AppScreen.CONTACTS),
|
||||
BottomNavItemData("Calls", R.drawable.ic_tag, AppScreen.CALLS),
|
||||
BottomNavItemData("Chats", R.drawable.ic_chat, AppScreen.CHATS),
|
||||
BottomNavItemData("Contacts", R.drawable.ic_home ,"home"),
|
||||
BottomNavItemData("Calls", R.drawable.ic_tag, "sell"),
|
||||
BottomNavItemData("Chats", R.drawable.ic_chat, "chats"),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
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()
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
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()
|
||||
}
|
||||
}
|
||||
|
|
@ -281,30 +281,30 @@ fun AppNavigation(
|
|||
)
|
||||
}
|
||||
|
||||
// composable(AppScreen.BUY_ANIMALS_FILTERS) {
|
||||
// FilterScreen(
|
||||
// onBackClick = {
|
||||
// navController.popBackStack()
|
||||
// },
|
||||
// onSubmitClick = {navController.navigate(AppScreen.BUY_ANIMALS)},
|
||||
// onCancelClick = {
|
||||
// navController.popBackStack()
|
||||
// },
|
||||
// )
|
||||
// }
|
||||
composable(AppScreen.BUY_ANIMALS_FILTERS) {
|
||||
FilterScreen(
|
||||
onBackClick = {
|
||||
navController.popBackStack()
|
||||
},
|
||||
onSubmitClick = {navController.navigate(AppScreen.BUY_ANIMALS)},
|
||||
onCancelClick = {
|
||||
navController.popBackStack()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// composable(AppScreen.BUY_ANIMALS_SORT) {
|
||||
// SortScreen(
|
||||
// onApplyClick = {navController.navigate(AppScreen.BUY_ANIMALS)},
|
||||
// onBackClick = {
|
||||
// navController.popBackStack()
|
||||
// },
|
||||
// onCancelClick = {
|
||||
// navController.popBackStack()
|
||||
// },
|
||||
//
|
||||
// )
|
||||
// }
|
||||
composable(AppScreen.BUY_ANIMALS_SORT) {
|
||||
SortScreen(
|
||||
onApplyClick = {navController.navigate(AppScreen.BUY_ANIMALS)},
|
||||
onBackClick = {
|
||||
navController.popBackStack()
|
||||
},
|
||||
onCancelClick = {
|
||||
navController.popBackStack()
|
||||
},
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
composable(AppScreen.SAVED_LISTINGS) {
|
||||
SavedListingsScreen(
|
||||
|
|
|
|||
|
|
@ -95,17 +95,17 @@ fun NavGraphBuilder.mainNavGraph(navController: NavController) {
|
|||
}
|
||||
|
||||
|
||||
// composable(AppScreen.BUY_ANIMALS_FILTERS) {
|
||||
// FilterScreen(
|
||||
// onBackClick = {
|
||||
// navController.popBackStack()
|
||||
// },
|
||||
// onSubmitClick = {navController.navigate(AppScreen.BUY_ANIMALS)},
|
||||
// onCancelClick = {
|
||||
// navController.popBackStack()
|
||||
// },
|
||||
// )
|
||||
// }
|
||||
composable(AppScreen.BUY_ANIMALS_FILTERS) {
|
||||
FilterScreen(
|
||||
onBackClick = {
|
||||
navController.popBackStack()
|
||||
},
|
||||
onSubmitClick = {navController.navigate(AppScreen.BUY_ANIMALS)},
|
||||
onCancelClick = {
|
||||
navController.popBackStack()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
composable(AppScreen.BUY_ANIMALS_SORT) {
|
||||
SortScreen(
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ fun BuyScreen(
|
|||
// Animal type filter buttons
|
||||
AnimalTypeSelector(
|
||||
animalTypes = animalTypes,
|
||||
selectedAnimalType =
|
||||
selectedAnimalType = selectedAnimalType
|
||||
) { }
|
||||
|
||||
// Ad space banner
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ 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
|
||||
|
|
@ -31,47 +30,42 @@ 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 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 selectedAnimal by remember { mutableStateOf("") }
|
||||
var selectedBreed by remember { mutableStateOf("") }
|
||||
var selectedDistance by remember { mutableStateOf("") }
|
||||
var selectedGender by remember { mutableStateOf("") }
|
||||
|
||||
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 price =filters.price
|
||||
var age = filters.age
|
||||
var weight = filters.weight
|
||||
var milkYield = filters.milkYield
|
||||
var calving = filters.calving
|
||||
var priceFrom by remember { mutableStateOf("0") }
|
||||
var priceTo by remember { mutableStateOf("90,000") }
|
||||
var priceSliderValue by remember { mutableFloatStateOf(0f) }
|
||||
|
||||
var selectedPregnancyStatus = filters.pregnancyStatuses
|
||||
var ageFrom by remember { mutableStateOf("1") }
|
||||
var ageTo by remember { mutableStateOf("20") }
|
||||
|
||||
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) }
|
||||
|
|
@ -79,7 +73,7 @@ fun FilterScreen(
|
|||
val maxCalving = 10
|
||||
|
||||
val calvingFromOptions = (0..maxCalving).map { it.toString() }
|
||||
val calvingToOptions = (calving.min..maxCalving).map { it.toString() }
|
||||
val calvingToOptions = (calvingFrom..maxCalving).map { it.toString() }
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
|
|
@ -115,21 +109,6 @@ 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"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -149,21 +128,15 @@ fun FilterScreen(
|
|||
) {
|
||||
DropdownInput(
|
||||
label = "Animal",
|
||||
selected = if (selectedAnimal.filterSet) selectedAnimal.value else "",
|
||||
selected = selectedAnimal,
|
||||
options = listOf("Cow", "Buffalo", "Goat", "Sheep"),
|
||||
expanded = animalExpanded,
|
||||
onExpandedChange = { animalExpanded = it },
|
||||
onSelect = { item ->
|
||||
filters = filters.copy(
|
||||
animal = TextFilter(
|
||||
value = item,
|
||||
filterSet = true
|
||||
)
|
||||
)
|
||||
selectedAnimal = item
|
||||
animalExpanded = false
|
||||
},
|
||||
placeholder = "Select Animal", // <--- half width
|
||||
textColor = if (selectedAnimal.filterSet) Color.Black else Color.Gray
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -173,21 +146,15 @@ fun FilterScreen(
|
|||
) {
|
||||
DropdownInput(
|
||||
label = "Breed",
|
||||
selected = if (selectedBreed.filterSet) selectedBreed.value else "",
|
||||
selected = selectedBreed,
|
||||
options = listOf("Holstein", "Jersey", "Gir", "Sahiwal"),
|
||||
expanded = breedExpanded,
|
||||
onExpandedChange = { breedExpanded = it },
|
||||
onSelect = { item ->
|
||||
filters = filters.copy(
|
||||
breed = TextFilter(
|
||||
value = item,
|
||||
filterSet = true
|
||||
)
|
||||
)
|
||||
selectedBreed = item
|
||||
breedExpanded = false
|
||||
},
|
||||
placeholder = "Select Breed", // <--- half width
|
||||
textColor = if (selectedAnimal.filterSet) Color.Black else Color.Gray
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -199,21 +166,14 @@ fun FilterScreen(
|
|||
) {
|
||||
RangeFilter(
|
||||
modifier = Modifier.fillMaxWidth(), // 👈 important
|
||||
|
||||
label = "Price",
|
||||
min = 0,
|
||||
max = 90_000,
|
||||
valueFrom = price.min,
|
||||
valueTo = price.max,
|
||||
modified = price.filterSet,
|
||||
valueFrom = priceFrom.toInt(),
|
||||
valueTo = priceTo.replace(",", "").toInt(),
|
||||
onValueChange = { from, to ->
|
||||
filters = filters.copy(
|
||||
price = RangeFilterState(
|
||||
min = from,
|
||||
max = to,
|
||||
filterSet = true
|
||||
)
|
||||
)
|
||||
priceFrom = from.toString()
|
||||
priceTo = to.toString()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
@ -223,26 +183,18 @@ fun FilterScreen(
|
|||
|
||||
) {
|
||||
RangeFilter(
|
||||
modifier = Modifier.fillMaxWidth(), // 👈 important
|
||||
|
||||
label = "Age (years)",
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
label = "Age",
|
||||
min = 0,
|
||||
max = 20,
|
||||
valueFrom = age.min,
|
||||
valueTo = age.max,
|
||||
valueFrom = ageFrom.toInt(),
|
||||
valueTo = ageTo.replace(",", "").toInt(),
|
||||
showSlider = false,
|
||||
modified = age.filterSet,
|
||||
onValueChange = { from, to ->
|
||||
filters = filters.copy(
|
||||
age = RangeFilterState(
|
||||
min = from,
|
||||
max = to,
|
||||
filterSet = true
|
||||
)
|
||||
)
|
||||
ageFrom = from.toString()
|
||||
ageTo = to.toString()
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -254,21 +206,15 @@ fun FilterScreen(
|
|||
) {
|
||||
DropdownInput(
|
||||
label = "Distance",
|
||||
selected = if (selectedDistance.filterSet) selectedDistance.value else "",
|
||||
selected = selectedDistance,
|
||||
options = listOf("0-5 km", "5-10 km", "10-20 km", "20+ km"),
|
||||
expanded = distanceExpanded,
|
||||
onExpandedChange = { distanceExpanded = it },
|
||||
onSelect = { item ->
|
||||
filters = filters.copy(
|
||||
distance = TextFilter(
|
||||
value = item,
|
||||
filterSet = true
|
||||
)
|
||||
)
|
||||
selectedDistance = item
|
||||
distanceExpanded = false
|
||||
},
|
||||
placeholder = "Choose Distance", // <--- half width
|
||||
textColor = if (selectedAnimal.filterSet) Color.Black else Color.Gray
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -278,21 +224,15 @@ fun FilterScreen(
|
|||
) {
|
||||
DropdownInput(
|
||||
label = "Gender",
|
||||
selected = if (selectedGender.filterSet) selectedGender.value else "",
|
||||
selected = selectedGender,
|
||||
options = listOf("Male", "Female"),
|
||||
expanded = genderExpanded,
|
||||
onExpandedChange = { genderExpanded = it },
|
||||
onSelect = { item ->
|
||||
filters = filters.copy(
|
||||
gender = TextFilter(
|
||||
value = item,
|
||||
filterSet = true
|
||||
)
|
||||
)
|
||||
selectedGender = item
|
||||
genderExpanded = false
|
||||
},
|
||||
placeholder = "Choose Gender", // <--- half width
|
||||
textColor = if (selectedAnimal.filterSet) Color.Black else Color.Gray
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -319,13 +259,11 @@ fun FilterScreen(
|
|||
label = status,
|
||||
isSelected = selectedPregnancyStatus.contains(status),
|
||||
onClick = {
|
||||
filters = filters.copy(
|
||||
pregnancyStatuses =
|
||||
if (filters.pregnancyStatuses.contains(status))
|
||||
filters.pregnancyStatuses - status
|
||||
else
|
||||
filters.pregnancyStatuses + status
|
||||
)
|
||||
selectedPregnancyStatus = if (selectedPregnancyStatus.contains(status)) {
|
||||
selectedPregnancyStatus - status
|
||||
} else {
|
||||
selectedPregnancyStatus + status
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
@ -338,21 +276,14 @@ fun FilterScreen(
|
|||
) {
|
||||
RangeFilter(
|
||||
modifier = Modifier.fillMaxWidth(), // 👈 important
|
||||
|
||||
label = "Weight",
|
||||
min = 0,
|
||||
max = 9000,
|
||||
valueFrom = weight.min,
|
||||
valueTo = weight.max,
|
||||
modified = weight.filterSet,
|
||||
valueFrom = weightFrom.toInt(),
|
||||
valueTo = weightTo.replace(",", "").toInt(),
|
||||
onValueChange = { from, to ->
|
||||
filters = filters.copy(
|
||||
weight = RangeFilterState(
|
||||
min = from,
|
||||
max = to,
|
||||
filterSet = true
|
||||
)
|
||||
)
|
||||
weightFrom = from.toString()
|
||||
weightTo = to.toString()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
@ -361,22 +292,16 @@ fun FilterScreen(
|
|||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
RangeFilter(
|
||||
modifier = Modifier.fillMaxWidth(), // 👈 important
|
||||
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
label = "Milk Yield",
|
||||
min = 0,
|
||||
max = 900,
|
||||
valueFrom = milkYield.min,
|
||||
valueTo = milkYield.max,
|
||||
modified = milkYield.filterSet,
|
||||
valueFrom = milkYieldFrom.toInt(),
|
||||
valueTo = milkYieldTo.replace(",", "").toInt(),
|
||||
showSlider = true,
|
||||
onValueChange = { from, to ->
|
||||
filters = filters.copy(
|
||||
milkYield = RangeFilterState(
|
||||
min = from,
|
||||
max = to,
|
||||
filterSet = true
|
||||
)
|
||||
)
|
||||
milkYieldFrom = from.toString()
|
||||
milkYieldTo = to.toString()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
@ -396,21 +321,18 @@ fun FilterScreen(
|
|||
// FROM
|
||||
DropdownInput(
|
||||
label = "Calving Number",
|
||||
selected = calving.min.toString(),
|
||||
selected = calvingFrom.toString(),
|
||||
options = calvingFromOptions,
|
||||
expanded = calvingFromExpanded,
|
||||
onExpandedChange = { calvingFromExpanded = it },
|
||||
onSelect = { value ->
|
||||
val newFrom = value.toInt()
|
||||
val newTo = maxOf(calving.max, newFrom)
|
||||
calvingFrom = newFrom
|
||||
|
||||
filters = filters.copy(
|
||||
calving = RangeFilterState(
|
||||
min = newFrom,
|
||||
max = newTo,
|
||||
filterSet = true
|
||||
)
|
||||
)
|
||||
// 👇 enforce invariant
|
||||
if (calvingTo < newFrom) {
|
||||
calvingTo = newFrom
|
||||
}
|
||||
|
||||
calvingFromExpanded = false
|
||||
},
|
||||
|
|
@ -426,21 +348,12 @@ fun FilterScreen(
|
|||
|
||||
// TO
|
||||
DropdownInput(
|
||||
selected = calving.max.toString(),
|
||||
selected = calvingTo.toString(),
|
||||
options = calvingToOptions, // 👈 constrained options
|
||||
expanded = calvingToExpanded,
|
||||
onExpandedChange = { calvingToExpanded = it },
|
||||
onSelect = { value ->
|
||||
val newTo = value.toInt()
|
||||
val newFrom = minOf(calving.min, newTo)
|
||||
|
||||
filters = filters.copy(
|
||||
calving = RangeFilterState(
|
||||
min = newFrom,
|
||||
max = newTo,
|
||||
filterSet = true
|
||||
)
|
||||
)
|
||||
calvingTo = value.toInt()
|
||||
calvingToExpanded = false
|
||||
},
|
||||
placeholder = "To",
|
||||
|
|
@ -459,7 +372,7 @@ fun FilterScreen(
|
|||
) {
|
||||
// Submit Button
|
||||
Button(
|
||||
onClick = { onSubmitClick(filters) },
|
||||
onClick = onSubmitClick,
|
||||
modifier = Modifier
|
||||
.width(173.dp)
|
||||
.height(50.dp),
|
||||
|
|
@ -501,20 +414,6 @@ fun FilterScreen(
|
|||
}
|
||||
}
|
||||
}
|
||||
if (showWishlistOverlay) {
|
||||
WishlistNameOverlay(
|
||||
onDismiss = { showWishlistOverlay = false },
|
||||
onSave = { name ->
|
||||
WishlistStore.add(
|
||||
WishlistEntry(
|
||||
name = name,
|
||||
filters = filters
|
||||
)
|
||||
)
|
||||
showWishlistOverlay = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
@ -539,8 +438,7 @@ fun PregnancyStatusChip(
|
|||
.clickable(
|
||||
indication = LocalIndication.current,
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
onClick = onClick
|
||||
)
|
||||
onClick = onClick)
|
||||
.padding(horizontal = 12.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@ 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,
|
||||
|
|
@ -103,14 +101,8 @@ fun CallsScreen(
|
|||
.fillMaxSize()
|
||||
.background(Color(0xFFFCFBF8))
|
||||
) {
|
||||
BottomNavScaffold(
|
||||
items = chatBottomNavItems,
|
||||
currentItem = "Calls",
|
||||
onBottomNavItemClick = onTabClick,
|
||||
) { paddingValues ->
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize().padding(paddingValues)
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
CallsHeader(
|
||||
onBackClick = onBackClick,
|
||||
|
|
@ -133,11 +125,10 @@ fun CallsScreen(
|
|||
}
|
||||
}
|
||||
|
||||
// ContactsBottomNav(
|
||||
// currentTab = ContactsTab.CALLS,
|
||||
// onTabClick = onTabClick
|
||||
// )
|
||||
}
|
||||
ContactsBottomNav(
|
||||
currentTab = ContactsTab.CALLS,
|
||||
onTabClick = onTabClick
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@ 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,
|
||||
|
|
@ -110,13 +108,8 @@ fun ChatsScreen(
|
|||
.fillMaxSize()
|
||||
.background(Color(0xFFFCFBF8))
|
||||
) {
|
||||
BottomNavScaffold(
|
||||
items = chatBottomNavItems,
|
||||
currentItem = "Chats",
|
||||
onBottomNavItemClick = onTabClick,
|
||||
) { paddingValues ->
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize().padding(paddingValues)
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
ChatsHeader(
|
||||
onBackClick = onBackClick,
|
||||
|
|
@ -139,11 +132,10 @@ fun ChatsScreen(
|
|||
}
|
||||
}
|
||||
|
||||
// ContactsBottomNav(
|
||||
// currentTab = ContactsTab.CHATS,
|
||||
// onTabClick = onTabClick
|
||||
// )
|
||||
}
|
||||
ContactsBottomNav(
|
||||
currentTab = ContactsTab.CHATS,
|
||||
onTabClick = onTabClick
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,9 +34,6 @@ 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(
|
||||
|
|
@ -125,14 +122,8 @@ fun ContactsScreen(
|
|||
.fillMaxSize()
|
||||
.background(Color(0xFFFCFBF8))
|
||||
) {
|
||||
BottomNavScaffold(
|
||||
items = chatBottomNavItems,
|
||||
currentItem = "Contacts",
|
||||
onBottomNavItemClick = onTabClick,
|
||||
) { paddingValues ->
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize().padding(paddingValues)
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
ContactsHeader(
|
||||
onBackClick = onBackClick,
|
||||
|
|
@ -155,11 +146,10 @@ fun ContactsScreen(
|
|||
}
|
||||
}
|
||||
|
||||
// ContactsBottomNav(
|
||||
// currentTab = ContactsTab.CONTACTS,
|
||||
// onTabClick = onTabClick
|
||||
// )
|
||||
}
|
||||
ContactsBottomNav(
|
||||
currentTab = ContactsTab.CONTACTS,
|
||||
onTabClick = onTabClick
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue