feat: refs#6659 jetPackCompose
This commit is contained in:
parent
16b84ce2ec
commit
aede2d4051
|
@ -2,6 +2,7 @@ package es.verdnatura.presentation.composable
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
|
@ -14,13 +15,18 @@ import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.KeyboardActions
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.PlainTooltip
|
||||||
import androidx.compose.material3.Switch
|
import androidx.compose.material3.Switch
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextField
|
import androidx.compose.material3.TextField
|
||||||
import androidx.compose.material3.TextFieldDefaults
|
import androidx.compose.material3.TextFieldDefaults
|
||||||
|
import androidx.compose.material3.TooltipBox
|
||||||
|
import androidx.compose.material3.TooltipDefaults
|
||||||
|
import androidx.compose.material3.rememberTooltipState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
@ -29,7 +35,6 @@ import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Alignment.Companion.CenterVertically
|
import androidx.compose.ui.Alignment.Companion.CenterVertically
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.focus.onFocusEvent
|
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||||
import androidx.compose.ui.res.colorResource
|
import androidx.compose.ui.res.colorResource
|
||||||
|
@ -45,15 +50,16 @@ import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import es.verdnatura.R
|
import es.verdnatura.R
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun CustomToolbar(
|
fun CustomToolbar(
|
||||||
title: String,
|
title: String,
|
||||||
subtitle: String? = null,
|
subtitle: String? = null,
|
||||||
showBackButton: Boolean = true,
|
showBackButton: Boolean = true,
|
||||||
showSwitch: Boolean = false,
|
showSwitch: Boolean = false,
|
||||||
iconList: List<Int> = emptyList(),
|
iconList: List<IconToolBar> = emptyList(),
|
||||||
onBackClick: () -> Unit = {},
|
onBackClick: () -> Unit = {},
|
||||||
onSwitchChange: (Boolean) -> Unit = {}
|
onSwitchChange: (Boolean) -> Unit = {},
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
@ -66,8 +72,9 @@ fun CustomToolbar(
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.height(56.dp),
|
.height(56.dp),
|
||||||
verticalAlignment = CenterVertically,
|
verticalAlignment = CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
|
|
||||||
) {
|
) {
|
||||||
if (showBackButton) {
|
if (showBackButton) {
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = { onBackClick() },
|
onClick = { onBackClick() },
|
||||||
|
@ -81,6 +88,7 @@ fun CustomToolbar(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Text(
|
Text(
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
text = title,
|
text = title,
|
||||||
color = Color.White,
|
color = Color.White,
|
||||||
fontSize = dimensionResource(id = R.dimen.title).value.sp,
|
fontSize = dimensionResource(id = R.dimen.title).value.sp,
|
||||||
|
@ -96,22 +104,40 @@ fun CustomToolbar(
|
||||||
fontSize = dimensionResource(id = R.dimen.subtitle).value.sp
|
fontSize = dimensionResource(id = R.dimen.subtitle).value.sp
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (iconList.isNotEmpty()) {
|
if (iconList.isNotEmpty()) {
|
||||||
LazyRow {
|
LazyRow(
|
||||||
items(iconList) { iconRes ->
|
horizontalArrangement = Arrangement.End, // Esto asegura que los iconos estén a la derecha
|
||||||
IconButton(onClick = { /* Acción del icono */ }) {
|
) {
|
||||||
Icon(
|
items(iconList) { iconToolBar ->
|
||||||
painter = painterResource(id = iconRes),
|
TooltipBox(
|
||||||
contentDescription = "Icon",
|
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
|
||||||
tint = Color.White
|
tooltip = {
|
||||||
)
|
PlainTooltip {
|
||||||
|
Text(iconToolBar.toolTip)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
state = rememberTooltipState()
|
||||||
|
) {
|
||||||
|
IconButton(
|
||||||
|
onClick = { iconToolBar.onClickIcon() },
|
||||||
|
) {
|
||||||
|
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = iconToolBar.idRes),
|
||||||
|
contentDescription = iconToolBar.toolTip,
|
||||||
|
tint = Color.White
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (showSwitch) {
|
if (showSwitch) {
|
||||||
var switchState by remember { mutableStateOf(false) }
|
var switchState by remember { mutableStateOf(false) }
|
||||||
Switch(
|
Switch(
|
||||||
|
@ -131,6 +157,14 @@ fun CustomToolbar(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class IconToolBar(
|
||||||
|
val idRes: Int,
|
||||||
|
val toolTip: String = "",
|
||||||
|
val tint: Color = Color.White,
|
||||||
|
val onClickIcon: () -> Unit,
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ScanLineTextSearch(
|
fun ScanLineTextSearch(
|
||||||
value: String,
|
value: String,
|
||||||
|
@ -153,17 +187,23 @@ fun ScanLineTextSearch(
|
||||||
textAlign = TextAlign.Center
|
textAlign = TextAlign.Center
|
||||||
),
|
),
|
||||||
placeholder = {
|
placeholder = {
|
||||||
Text(
|
Box(
|
||||||
text = stringResource(id = R.string.Escaneaetiqueta),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
textAlign = TextAlign.Center,
|
contentAlignment = Alignment.Center
|
||||||
color = Color.White,
|
) {
|
||||||
modifier = Modifier.fillMaxWidth()
|
Text(
|
||||||
)
|
text = stringResource(id = R.string.Escaneaetiqueta),
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
color = Color.White,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
keyboardActions = KeyboardActions(
|
keyboardActions = KeyboardActions(
|
||||||
onDone = {
|
onDone = {
|
||||||
onImeAction()
|
onImeAction()
|
||||||
|
keyboardController?.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
),
|
),
|
||||||
|
@ -182,13 +222,12 @@ fun ScanLineTextSearch(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.fillMaxWidth(fraction = 0.67f)
|
.fillMaxWidth(fraction = 0.67f)
|
||||||
.border(2.dp, Color.White, RoundedCornerShape(8.dp))
|
.border(2.dp, Color.White, RoundedCornerShape(8.dp))
|
||||||
.height(54.dp)
|
.height(52.dp)
|
||||||
.padding(bottom = 4.dp)
|
/* .onFocusEvent {
|
||||||
.onFocusEvent {
|
|
||||||
if (it.isFocused) {
|
if (it.isFocused) {
|
||||||
keyboardController?.hide()
|
keyboardController?.hide()
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -202,7 +241,12 @@ fun PreviewToolbar() {
|
||||||
subtitle = "10/20",
|
subtitle = "10/20",
|
||||||
showBackButton = true,
|
showBackButton = true,
|
||||||
showSwitch = true,
|
showSwitch = true,
|
||||||
iconList = listOf(R.drawable.ic_launcher_foreground, R.drawable.ic_launcher_foreground),
|
iconList = listOf(
|
||||||
|
IconToolBar(
|
||||||
|
R.drawable.ic_parking_ui, "", tint = Color.Blue,
|
||||||
|
onClickIcon = { }
|
||||||
|
)
|
||||||
|
),
|
||||||
onBackClick = { /* Acción de volver atrás */ },
|
onBackClick = { /* Acción de volver atrás */ },
|
||||||
onSwitchChange = { /* Acción del switch */ }
|
onSwitchChange = { /* Acción del switch */ }
|
||||||
)
|
)
|
||||||
|
@ -212,7 +256,7 @@ fun PreviewToolbar() {
|
||||||
@Composable
|
@Composable
|
||||||
fun PreviewScanLineTextSearch() {
|
fun PreviewScanLineTextSearch() {
|
||||||
ScanLineTextSearch(
|
ScanLineTextSearch(
|
||||||
value = "Escanea etiqueta",
|
value = stringResource(R.string.scanLabel),
|
||||||
onValueChange = {},
|
onValueChange = {},
|
||||||
onImeAction = {})
|
onImeAction = {})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package es.verdnatura.presentation.view.feature.buscaritem.fragment
|
package es.verdnatura.presentation.composable
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.fadeIn
|
import androidx.compose.animation.fadeIn
|
|
@ -0,0 +1,71 @@
|
||||||
|
package es.verdnatura.presentation.composable.ui
|
||||||
|
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
|
||||||
|
object VerdnaturaColors {
|
||||||
|
|
||||||
|
val OrangeSalix = Color(0xFFEC8916)
|
||||||
|
val BlackCustomDialog = Color(0xFF1A1A1A)
|
||||||
|
val White = Color(0xFFFFFFFF)
|
||||||
|
|
||||||
|
// Colores principales
|
||||||
|
val ColorPrimary = Color(0xFFF7931E)
|
||||||
|
val ColorPrimaryDark = Color(0xFF8B4200)
|
||||||
|
|
||||||
|
// Negros
|
||||||
|
/* val Black = Color(0xFF000000)
|
||||||
|
val Black1 = Color(0xFF1D1D1D)
|
||||||
|
val Black2 = Color(0xFF171717)
|
||||||
|
val Black3 = Color(0xFF292929)
|
||||||
|
val Black4 = Color(0xFF242424)
|
||||||
|
val Black5 = Color(0xFF323232)
|
||||||
|
val Black6 = Color(0xFF333333)
|
||||||
|
val Black7 = Color(0xFF282828)
|
||||||
|
val Black8 = Color(0xFF1A1A1A)
|
||||||
|
val BlackCustomDialog = Color(0xFF464446)
|
||||||
|
val Black8Alpha6 = Color(0x991A1A1A) // Con transparencia
|
||||||
|
|
||||||
|
// Grises
|
||||||
|
val WarmGrey = Color(0xFF707070)
|
||||||
|
val BrownGrey = Color(0xFF8F8F8F)
|
||||||
|
val BrownGreyLight = Color(0xFFB8ADAD)
|
||||||
|
|
||||||
|
// Colores vivos
|
||||||
|
val Red = Color(0xFFE74C3C)
|
||||||
|
val WarmBrown = Color(0xFF8B4200)
|
||||||
|
val PumpkinOrange = Color(0xFFF7931E)
|
||||||
|
val PumpkinLight = Color(0xFFF77956)
|
||||||
|
val PinkSalix = Color(0xFFFF99CC)
|
||||||
|
val SunflowerYellow = Color(0xFFFFD400)
|
||||||
|
val DarkSkyBlue = Color(0xFF4AB4E6)
|
||||||
|
val DarkGreenVerdnatura = Color(0xFFA3D131)
|
||||||
|
val DarkMint = Color(0xFF50BE87)
|
||||||
|
val DarkMintLight = Color(0xFF80BE87)
|
||||||
|
val DarkMintLightPrecontrolled = Color(0xFFB8DABA)
|
||||||
|
val LightTeal = Color(0xFFB8ECD6)
|
||||||
|
val White = Color(0xFFFFFFFF)
|
||||||
|
val RedSalix = Color(0xFFFB5252)
|
||||||
|
val OrangeSalix = Color(0xFFEC8916)
|
||||||
|
|
||||||
|
// Fondos
|
||||||
|
val BackgroundItemPicker = Color(0xFF4D4D4D)
|
||||||
|
val BackgroundSubtitleSettings = Color(0xFF1A1A1A)
|
||||||
|
val BackgroundItemsMenus = Color(0xFF333333)
|
||||||
|
|
||||||
|
// Colores SALIX
|
||||||
|
val SalixSuccessLight = Color(0xFFA3D131)
|
||||||
|
val ColorHeader = Color(0xFF3D3D3D)
|
||||||
|
val ColorMenuHeader = Color(0xFF3D3D3D)
|
||||||
|
val ColorBg = Color(0xFF222222)
|
||||||
|
val ColorBgDark = Color(0xFF222222)
|
||||||
|
val ColorActive = Color(0xFF666666)
|
||||||
|
val ColorActiveFont = Color(0xFFFFFFFF)
|
||||||
|
val ColorBgPanel = Color(0xFF3C3B3B)
|
||||||
|
val ColorMain = ColorPrimary
|
||||||
|
val ColorMarginal = Color(0xFF222222)
|
||||||
|
val ColorSuccess = Color(0xFFA3D131)
|
||||||
|
val ColorNotice = Color(0xFF32B1CE)
|
||||||
|
val ColorAlert = Color(0xFFFA3939)
|
||||||
|
val ColorPink = Color(0xFFFF99CC)
|
||||||
|
val ColorYellow = Color(0xFFFFFF00)*/
|
||||||
|
}
|
|
@ -0,0 +1,167 @@
|
||||||
|
package es.verdnatura.presentation.composable.ui
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.border
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.ButtonDefaults
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextField
|
||||||
|
import androidx.compose.material3.TextFieldDefaults
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
|
import androidx.compose.ui.focus.focusRequester
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun DefaultButtonCustomDialog(
|
||||||
|
text: String,
|
||||||
|
onClick: () -> Unit = {},
|
||||||
|
enabled: Boolean = true,
|
||||||
|
leadingIcon: @Composable (() -> Unit)? = null
|
||||||
|
) {
|
||||||
|
Button(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
onClick = onClick,
|
||||||
|
enabled = enabled,
|
||||||
|
contentPadding = PaddingValues(
|
||||||
|
start = if (leadingIcon == null) 16.dp else 8.dp,
|
||||||
|
end = 16.dp
|
||||||
|
),
|
||||||
|
shape = MaterialTheme.shapes.small,
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
containerColor = VerdnaturaColors.ColorPrimary,
|
||||||
|
contentColor = VerdnaturaColors.White
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if (leadingIcon != null) {
|
||||||
|
leadingIcon()
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = text.uppercase(),
|
||||||
|
fontSize = 14.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TitleTextCustomDialog(
|
||||||
|
title: String,
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = title,
|
||||||
|
style = MaterialTheme.typography.titleLarge.copy(
|
||||||
|
fontWeight = FontWeight.Bold
|
||||||
|
),
|
||||||
|
color = VerdnaturaColors.White,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(bottom = 8.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun DescriptionTextCustomDialog(
|
||||||
|
description: String,
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = description,
|
||||||
|
color = VerdnaturaColors.White,
|
||||||
|
modifier = Modifier.padding(bottom = 8.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ScanTextCustomDialog(
|
||||||
|
value: TextFieldValue,
|
||||||
|
onValueChange: (TextFieldValue) -> Unit,
|
||||||
|
hint: String,
|
||||||
|
onEnterPressed: (String) -> Unit = {},
|
||||||
|
focusRequester: FocusRequester
|
||||||
|
) {
|
||||||
|
val keyboardController = LocalSoftwareKeyboardController.current
|
||||||
|
|
||||||
|
TextField(
|
||||||
|
value = value,
|
||||||
|
onValueChange = onValueChange,
|
||||||
|
label = {
|
||||||
|
Text(
|
||||||
|
text = hint,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
color = Color.White,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(horizontal = 16.dp),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.focusRequester(focusRequester)
|
||||||
|
.border(1.dp, Color.White, shape = MaterialTheme.shapes.small)
|
||||||
|
.background(Color.Transparent)
|
||||||
|
.height(VerdnaturaDimens.minHeight),
|
||||||
|
textStyle = CustomTextStyle,
|
||||||
|
keyboardOptions =
|
||||||
|
KeyboardOptions.Default.copy(
|
||||||
|
imeAction = ImeAction.Done,
|
||||||
|
keyboardType = KeyboardType.Number
|
||||||
|
),
|
||||||
|
singleLine = true,
|
||||||
|
keyboardActions = KeyboardActions(
|
||||||
|
onDone = {
|
||||||
|
onEnterPressed(value.text)
|
||||||
|
onValueChange(TextFieldValue(""))
|
||||||
|
keyboardController?.hide()
|
||||||
|
}
|
||||||
|
),
|
||||||
|
colors = TextFieldDefaults.colors(
|
||||||
|
focusedContainerColor = Color.Transparent,
|
||||||
|
unfocusedContainerColor = Color.Transparent,
|
||||||
|
focusedTextColor = VerdnaturaColors.White,
|
||||||
|
unfocusedTextColor = VerdnaturaColors.White
|
||||||
|
)
|
||||||
|
)
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
focusRequester.requestFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
fun PreviewCustomTextField() {
|
||||||
|
val sampleText = remember { mutableStateOf(TextFieldValue("Texto de ejemplo")) }
|
||||||
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
ScanTextCustomDialog(
|
||||||
|
value = sampleText.value,
|
||||||
|
onValueChange = { sampleText.value = it },
|
||||||
|
hint = "Escribe algo...",
|
||||||
|
onEnterPressed = { text -> println("Texto ingresado: $text") },
|
||||||
|
focusRequester = focusRequester
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package es.verdnatura.presentation.composable.ui
|
||||||
|
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
|
||||||
|
object VerdnaturaDimens {
|
||||||
|
|
||||||
|
/* val h1 = 96.sp
|
||||||
|
val h2 = 60.sp
|
||||||
|
val h3 = 48.sp
|
||||||
|
val h4 = 34.sp
|
||||||
|
val h5 = 24.sp
|
||||||
|
val h6 = 20.sp
|
||||||
|
val h7 = 18.sp
|
||||||
|
val h9 = 14.sp*/
|
||||||
|
|
||||||
|
// Text sizes
|
||||||
|
val fontSizeCustomDialogs = 16.sp
|
||||||
|
|
||||||
|
// Height Scan Text
|
||||||
|
val minHeight = 48.dp
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package es.verdnatura.presentation.composable.ui
|
||||||
|
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
|
||||||
|
val CustomTextStyle = TextStyle(
|
||||||
|
color = VerdnaturaColors.White,
|
||||||
|
fontSize = VerdnaturaDimens.fontSizeCustomDialogs,
|
||||||
|
textAlign = TextAlign.Center
|
||||||
|
)
|
|
@ -0,0 +1,119 @@
|
||||||
|
package es.verdnatura.presentation.view.component
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
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.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
|
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||||
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.window.Dialog
|
||||||
|
import es.verdnatura.presentation.composable.ui.DefaultButtonCustomDialog
|
||||||
|
import es.verdnatura.presentation.composable.ui.DescriptionTextCustomDialog
|
||||||
|
import es.verdnatura.presentation.composable.ui.ScanTextCustomDialog
|
||||||
|
import es.verdnatura.presentation.composable.ui.TitleTextCustomDialog
|
||||||
|
import es.verdnatura.presentation.composable.ui.VerdnaturaColors
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun CustomDialogListComposable(
|
||||||
|
title: String = "",
|
||||||
|
description: String = "",
|
||||||
|
buttonOkText: String = "",
|
||||||
|
onOkClick: () -> Unit = {},
|
||||||
|
showRecyclerView: Boolean = true,
|
||||||
|
recyclerViewItems: List<Number> = listOf(),
|
||||||
|
onItemSelected: (Number) -> Unit = {},
|
||||||
|
hintOne: String = "",
|
||||||
|
onEnterPressed: (String) -> Unit = {}
|
||||||
|
) {
|
||||||
|
var valueOne by remember { mutableStateOf(TextFieldValue()) }
|
||||||
|
val showDialog = remember { mutableStateOf(true) }
|
||||||
|
val keyboardController = LocalSoftwareKeyboardController.current
|
||||||
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
|
||||||
|
if (showDialog.value) {
|
||||||
|
Dialog(
|
||||||
|
onDismissRequest = { showDialog.value = false },
|
||||||
|
) {
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.background(VerdnaturaColors.BlackCustomDialog)
|
||||||
|
.padding(16.dp),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
) {
|
||||||
|
if (title.isNotEmpty()) {
|
||||||
|
TitleTextCustomDialog(title)
|
||||||
|
}
|
||||||
|
if (description.isNotEmpty()) {
|
||||||
|
DescriptionTextCustomDialog(description)
|
||||||
|
}
|
||||||
|
|
||||||
|
ScanTextCustomDialog(
|
||||||
|
value = valueOne,
|
||||||
|
onValueChange = { valueOne = it },
|
||||||
|
hint = hintOne,
|
||||||
|
onEnterPressed = onEnterPressed,
|
||||||
|
focusRequester = focusRequester
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
|
if (showRecyclerView && recyclerViewItems.isNotEmpty()) {
|
||||||
|
LazyColumn(modifier = Modifier.fillMaxWidth()) {
|
||||||
|
items(recyclerViewItems) { item ->
|
||||||
|
Text(
|
||||||
|
text = item.toString(),
|
||||||
|
color = VerdnaturaColors.White,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(8.dp)
|
||||||
|
.clickable {
|
||||||
|
onItemSelected(item)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultButtonCustomDialog(buttonOkText, onClick = {
|
||||||
|
onOkClick()
|
||||||
|
keyboardController?.hide()
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun PreviewCustomDialogList() {
|
||||||
|
|
||||||
|
CustomDialogListComposable(
|
||||||
|
title = "Custom Dialog Title",
|
||||||
|
description = "This is a description.",
|
||||||
|
buttonOkText = "OK",
|
||||||
|
onOkClick = { /* Handle OK click */ },
|
||||||
|
showRecyclerView = true,
|
||||||
|
recyclerViewItems = listOf(1, 2, 3),
|
||||||
|
onItemSelected = { item -> println("Item selected: $item") },
|
||||||
|
hintOne = "Hint for input one",
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
|
@ -11,7 +11,8 @@ import retrofit2.Response
|
||||||
|
|
||||||
data class UiState(
|
data class UiState(
|
||||||
val itemFk: String? = null,
|
val itemFk: String? = null,
|
||||||
val items: List<ItemShelvings> = emptyList()
|
val items: List<ItemShelvings> = emptyList(),
|
||||||
|
val isLoading: Boolean = false
|
||||||
)
|
)
|
||||||
|
|
||||||
class BuscarItemComposeViewModel(var application: android.app.Application) :
|
class BuscarItemComposeViewModel(var application: android.app.Application) :
|
||||||
|
@ -21,23 +22,8 @@ class BuscarItemComposeViewModel(var application: android.app.Application) :
|
||||||
private val _uiState = MutableStateFlow(UiState())
|
private val _uiState = MutableStateFlow(UiState())
|
||||||
val uiState = _uiState.asStateFlow()
|
val uiState = _uiState.asStateFlow()
|
||||||
|
|
||||||
/* private val _itemFk = MutableStateFlow<String?>(null)
|
|
||||||
val itemFk = _itemFk.asStateFlow()*/
|
|
||||||
|
|
||||||
/* private val _itemShelvingsList = MutableStateFlow<ItemShelvingsList?>(null)
|
|
||||||
val itemShelvingsList = _itemShelvingsList.asStateFlow()*/
|
|
||||||
|
|
||||||
/*val loadItemShelvingsList = _itemShelvingsList.map {
|
|
||||||
it?.let { Event(it) }
|
|
||||||
}.stateIn(
|
|
||||||
scope = viewModelScope,
|
|
||||||
started = SharingStarted.WhileSubscribed(5000),
|
|
||||||
initialValue = null
|
|
||||||
)*/
|
|
||||||
|
|
||||||
fun getIdFromCodeSalix(code: String) {
|
fun getIdFromCodeSalix(code: String) {
|
||||||
_uiState.update { it.copy(itemFk = code) }
|
_uiState.update { it.copy(itemFk = code, isLoading = true) }
|
||||||
//_itemFk.value = code
|
|
||||||
getItemFromBarcodeUseCase.execute(code)
|
getItemFromBarcodeUseCase.execute(code)
|
||||||
.enqueue(object : SalixCallback<Int?>(application.applicationContext) {
|
.enqueue(object : SalixCallback<Int?>(application.applicationContext) {
|
||||||
override fun onSuccess(response: Response<Int?>) {
|
override fun onSuccess(response: Response<Int?>) {
|
||||||
|
@ -45,7 +31,13 @@ class BuscarItemComposeViewModel(var application: android.app.Application) :
|
||||||
itemshelvingsGet(id)
|
itemshelvingsGet(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
override fun onError(t: Throwable) {
|
||||||
|
super.onError(t)
|
||||||
|
_uiState.update { it.copy(isLoading = false) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun itemshelvingsGet(itemFk: Any) {
|
fun itemshelvingsGet(itemFk: Any) {
|
||||||
|
@ -57,10 +49,14 @@ class BuscarItemComposeViewModel(var application: android.app.Application) :
|
||||||
.enqueue(object : SalixCallback<List<ItemShelvings>>(application.applicationContext) {
|
.enqueue(object : SalixCallback<List<ItemShelvings>>(application.applicationContext) {
|
||||||
override fun onSuccess(response: Response<List<ItemShelvings>>) {
|
override fun onSuccess(response: Response<List<ItemShelvings>>) {
|
||||||
response.body()?.let { list ->
|
response.body()?.let { list ->
|
||||||
//_itemShelvingsList.value = ItemShelvingsList(list)
|
_uiState.update { it.copy(items = list, isLoading = false) }
|
||||||
_uiState.update { it.copy(items = list) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onError(t: Throwable) {
|
||||||
|
super.onError(t)
|
||||||
|
_uiState.update { it.copy(isLoading = false) }
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,10 +6,8 @@ import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.ui.platform.ComposeView
|
import androidx.compose.ui.platform.ComposeView
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|
||||||
import es.verdnatura.R
|
import es.verdnatura.R
|
||||||
import es.verdnatura.domain.toast
|
import es.verdnatura.domain.toast
|
||||||
import es.verdnatura.presentation.common.OnPasillerosItemClickListener
|
import es.verdnatura.presentation.common.OnPasillerosItemClickListener
|
||||||
|
@ -39,7 +37,18 @@ class BuscarItemFragmentCompose(
|
||||||
): View {
|
): View {
|
||||||
return ComposeView(requireContext()).apply {
|
return ComposeView(requireContext()).apply {
|
||||||
setContent {
|
setContent {
|
||||||
SetView()
|
BuscarItemScreen(
|
||||||
|
viewModel = viewModel,
|
||||||
|
onBackClick = { (context as MainActivity).onMyBackPressed() },
|
||||||
|
onItemLongClick = { sector -> sector.toast(requireContext()) },
|
||||||
|
onItemClick = { shelving ->
|
||||||
|
pasillerosItemClickListener?.onPasillerosItemClickListener(
|
||||||
|
PasillerosItemVO(title = R.string.titleUbicator),
|
||||||
|
shelving
|
||||||
|
)
|
||||||
|
},
|
||||||
|
title = getString(R.string.getubication)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,12 +77,16 @@ class BuscarItemFragmentCompose(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun SetView() {
|
private fun SetView() {
|
||||||
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Como estaba
|
||||||
LocationScreen(
|
LocationScreen(
|
||||||
items = uiState.items.map {
|
items = uiState.items.map {
|
||||||
LocationItem(
|
LocationItem(
|
||||||
parking = it.shelving.parking.code,
|
parking = it.shelving.parking!!.code,
|
||||||
matricula = it.shelving.code,
|
matricula = it.shelving.code,
|
||||||
visible = it.visible.toString(),
|
visible = it.visible.toString(),
|
||||||
reserve = it.available.toString(),
|
reserve = it.available.toString(),
|
||||||
|
@ -85,7 +98,7 @@ class BuscarItemFragmentCompose(
|
||||||
onTextChange = { input ->
|
onTextChange = { input ->
|
||||||
viewModel.getIdFromCodeSalix(input)
|
viewModel.getIdFromCodeSalix(input)
|
||||||
},
|
},
|
||||||
titleToolBar = if (uiState.items.isNotEmpty()) {
|
titleToolBar = if (uiState.itemFk != null) {
|
||||||
getString(
|
getString(
|
||||||
R.string.itemsTotal,
|
R.string.itemsTotal,
|
||||||
uiState.itemFk,
|
uiState.itemFk,
|
||||||
|
@ -106,7 +119,6 @@ class BuscarItemFragmentCompose(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
class BuscarItemViewModelFactory(private val context: Application) : ViewModelProvider.Factory {
|
class BuscarItemViewModelFactory(private val context: Application) : ViewModelProvider.Factory {
|
||||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||||
if (modelClass.isAssignableFrom(BuscarItemComposeViewModel::class.java)) {
|
if (modelClass.isAssignableFrom(BuscarItemComposeViewModel::class.java)) {
|
||||||
|
|
|
@ -22,24 +22,196 @@ import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.focus.onFocusEvent
|
import androidx.compose.ui.focus.onFocusEvent
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import es.verdnatura.R
|
import es.verdnatura.R
|
||||||
import es.verdnatura.presentation.composable.CustomToolbar
|
import es.verdnatura.presentation.composable.CustomToolbar
|
||||||
|
import es.verdnatura.presentation.composable.LottieLoadingAnimation
|
||||||
import es.verdnatura.presentation.composable.ScanLineTextSearch
|
import es.verdnatura.presentation.composable.ScanLineTextSearch
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun BuscarItemScreen(
|
||||||
|
viewModel: BuscarItemComposeViewModel,
|
||||||
|
onBackClick: () -> Unit,
|
||||||
|
onItemLongClick: (sector: String) -> Unit,
|
||||||
|
onItemClick: (matricula: String) -> Unit,
|
||||||
|
title: String
|
||||||
|
) {
|
||||||
|
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
|
val locationItems = uiState.items
|
||||||
|
.filter { it.shelving.parking != null }
|
||||||
|
.map {
|
||||||
|
LocationItem(
|
||||||
|
parking = it.shelving.parking!!.code,
|
||||||
|
matricula = it.shelving.code,
|
||||||
|
visible = it.visible.toString(),
|
||||||
|
reserve = it.available.toString(),
|
||||||
|
priority = it.shelving.priority.toString(),
|
||||||
|
fecha = it.created,
|
||||||
|
sector = it.shelving.parking.sector.description
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
LocationScreenContent(
|
||||||
|
items = locationItems,
|
||||||
|
isLoading = uiState.isLoading,
|
||||||
|
titleToolBar = if (uiState.itemFk != null) {
|
||||||
|
LocalContext.current.getString(
|
||||||
|
R.string.itemsTotal,
|
||||||
|
uiState.itemFk,
|
||||||
|
LocalContext.current.getString(R.string.visibleTotal),
|
||||||
|
uiState.items
|
||||||
|
.filter { it.shelving.parking != null }
|
||||||
|
.sumOf { it.visible }
|
||||||
|
)
|
||||||
|
} else title,
|
||||||
|
onTextChange = { input -> viewModel.getIdFromCodeSalix(input) },
|
||||||
|
onBackClick = onBackClick,
|
||||||
|
onLongClick = onItemLongClick,
|
||||||
|
onClick = onItemClick,
|
||||||
|
modifier = Modifier
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun LocationScreenContent(
|
||||||
|
items: List<LocationItem>,
|
||||||
|
isLoading: Boolean,
|
||||||
|
titleToolBar: String,
|
||||||
|
onTextChange: (String) -> Unit,
|
||||||
|
onBackClick: () -> Unit,
|
||||||
|
onLongClick: (String) -> Unit,
|
||||||
|
onClick: (String) -> Unit,
|
||||||
|
modifier: Modifier
|
||||||
|
) {
|
||||||
|
var searchText by remember { mutableStateOf("") }
|
||||||
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
val keyboardController = LocalSoftwareKeyboardController.current
|
||||||
|
|
||||||
|
val onImeAction: () -> Unit = {
|
||||||
|
onTextChange(searchText)
|
||||||
|
searchText = ""
|
||||||
|
keyboardController?.hide()
|
||||||
|
}
|
||||||
|
Box(
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(Color.Black)
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(Color.Black)
|
||||||
|
|
||||||
|
) {
|
||||||
|
|
||||||
|
CustomToolbar(
|
||||||
|
title = titleToolBar,
|
||||||
|
subtitle = "",
|
||||||
|
showBackButton = true,
|
||||||
|
showSwitch = false,
|
||||||
|
iconList = listOf(),
|
||||||
|
onBackClick = onBackClick,
|
||||||
|
onSwitchChange = { },
|
||||||
|
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
|
|
||||||
|
ScanLineTextSearch(
|
||||||
|
value = searchText,
|
||||||
|
onValueChange = {
|
||||||
|
searchText = it
|
||||||
|
},
|
||||||
|
onImeAction,
|
||||||
|
modifier = Modifier
|
||||||
|
.focusRequester(focusRequester)
|
||||||
|
.onFocusEvent {
|
||||||
|
if (it.isFocused) {
|
||||||
|
keyboardController?.hide() // Asegura que el teclado no se abra
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
focusRequester.requestFocus()
|
||||||
|
keyboardController?.hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 8.dp),
|
||||||
|
horizontalArrangement = Arrangement.Start
|
||||||
|
) {
|
||||||
|
listOf(
|
||||||
|
R.string.parking,
|
||||||
|
R.string.Matrícula,
|
||||||
|
R.string.Visible,
|
||||||
|
R.string.reserve,
|
||||||
|
R.string.priority,
|
||||||
|
R.string.date
|
||||||
|
).forEach { textRes ->
|
||||||
|
Text(
|
||||||
|
text = stringResource(id = textRes),
|
||||||
|
color = Color.White,
|
||||||
|
fontSize = 14.sp,
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HorizontalDivider(thickness = 1.dp, color = Color.White)
|
||||||
|
LazyColumn(
|
||||||
|
modifier = Modifier.fillMaxSize()
|
||||||
|
) {
|
||||||
|
|
||||||
|
items(items) { item ->
|
||||||
|
|
||||||
|
LocationRow(
|
||||||
|
item = item,
|
||||||
|
onLongClick = { selectedItem ->
|
||||||
|
onLongClick(selectedItem.sector)
|
||||||
|
},
|
||||||
|
onClick = { selectedItem ->
|
||||||
|
onClick(selectedItem.matricula)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
HorizontalDivider(thickness = 1.dp, color = Color.White)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isLoading) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(Color.Black.copy(alpha = 0.7f)),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
LottieLoadingAnimation(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Como estaba
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun LocationScreen(
|
fun LocationScreen(
|
||||||
//viewModel: BuscarItemComposeViewModel = viewModel(), // Falta ver de arreglar con koin o viewmodel → No necesario, en el Fragment observa
|
//viewModel: ViewModel?, // Falta ver de arreglar con koin o viewmodel → No necesario, en el Fragment observa
|
||||||
items: List<LocationItem>,
|
items: List<LocationItem>,
|
||||||
onTextChange: (String) -> Unit,
|
onTextChange: (String) -> Unit,
|
||||||
titleToolBar: String,
|
titleToolBar: String,
|
||||||
|
@ -48,6 +220,7 @@ fun LocationScreen(
|
||||||
onLongClick: (LocationItem) -> Unit,
|
onLongClick: (LocationItem) -> Unit,
|
||||||
onClick: (LocationItem) -> Unit
|
onClick: (LocationItem) -> Unit
|
||||||
) {
|
) {
|
||||||
|
|
||||||
var searchText by remember { mutableStateOf("") }
|
var searchText by remember { mutableStateOf("") }
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
val keyboardController = LocalSoftwareKeyboardController.current
|
val keyboardController = LocalSoftwareKeyboardController.current
|
||||||
|
@ -117,7 +290,7 @@ fun LocationScreen(
|
||||||
R.string.Visible,
|
R.string.Visible,
|
||||||
R.string.reserve,
|
R.string.reserve,
|
||||||
R.string.priority,
|
R.string.priority,
|
||||||
R.string.Fecha
|
R.string.date
|
||||||
).forEach { textRes ->
|
).forEach { textRes ->
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(id = textRes),
|
text = stringResource(id = textRes),
|
||||||
|
@ -193,7 +366,6 @@ data class LocationItem(
|
||||||
@Composable
|
@Composable
|
||||||
fun PreviewLocationScreen() {
|
fun PreviewLocationScreen() {
|
||||||
LocationScreen(
|
LocationScreen(
|
||||||
// viewModel = null,
|
|
||||||
items = listOf(
|
items = listOf(
|
||||||
LocationItem("P1", "1234ABC", "Sí", "No", "Alta", "12/02/2025", "previa"),
|
LocationItem("P1", "1234ABC", "Sí", "No", "Alta", "12/02/2025", "previa"),
|
||||||
LocationItem("P2", "5678DEF", "No", "Sí", "Baja", "13/02/2025", "previa")
|
LocationItem("P2", "5678DEF", "No", "Sí", "Baja", "13/02/2025", "previa")
|
||||||
|
|
|
@ -0,0 +1,215 @@
|
||||||
|
package es.verdnatura.presentation.view.feature.diadeventa.fragment
|
||||||
|
|
||||||
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.combinedClickable
|
||||||
|
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.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.material3.HorizontalDivider
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
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.focus.FocusRequester
|
||||||
|
import androidx.compose.ui.focus.focusRequester
|
||||||
|
import androidx.compose.ui.focus.onFocusEvent
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import es.verdnatura.R
|
||||||
|
import es.verdnatura.presentation.composable.CustomToolbar
|
||||||
|
import es.verdnatura.presentation.composable.IconToolBar
|
||||||
|
import es.verdnatura.presentation.composable.LottieLoadingAnimation
|
||||||
|
import es.verdnatura.presentation.composable.ScanLineTextSearch
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Date
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun GenericListScreen(
|
||||||
|
items: List<List<String>>, // Lista de listas de strings para los datos
|
||||||
|
headers: List<String>,// Lista de encabezados
|
||||||
|
columnActions: List<(List<String>) -> Unit>, // Lista de acciones
|
||||||
|
onTextChange: (String) -> Unit,
|
||||||
|
titleToolBar: String,
|
||||||
|
onBackClick: () -> Unit = {},
|
||||||
|
onLongClick: (List<String>) -> Unit,
|
||||||
|
onClick: (List<String>) -> Unit,
|
||||||
|
listIconToolBar: List<IconToolBar> = listOf()
|
||||||
|
) {
|
||||||
|
var searchText by remember { mutableStateOf("") }
|
||||||
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
val keyboardController = LocalSoftwareKeyboardController.current
|
||||||
|
var showLoading by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
val onImeAction: () -> Unit = {
|
||||||
|
onTextChange(searchText)
|
||||||
|
searchText = ""
|
||||||
|
keyboardController?.hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(Color.Black)
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(Color.Black)
|
||||||
|
) {
|
||||||
|
if (showLoading) {
|
||||||
|
LottieLoadingAnimation(true)
|
||||||
|
}
|
||||||
|
CustomToolbar(
|
||||||
|
title = titleToolBar,
|
||||||
|
subtitle = "",
|
||||||
|
showBackButton = true,
|
||||||
|
showSwitch = false,
|
||||||
|
iconList = listIconToolBar,
|
||||||
|
onBackClick = onBackClick,
|
||||||
|
onSwitchChange = { }
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
|
ScanLineTextSearch(
|
||||||
|
value = searchText,
|
||||||
|
onValueChange = {
|
||||||
|
searchText = it
|
||||||
|
showLoading = true
|
||||||
|
},
|
||||||
|
onImeAction,
|
||||||
|
modifier = Modifier
|
||||||
|
.focusRequester(focusRequester)
|
||||||
|
.onFocusEvent {
|
||||||
|
if (it.isFocused) {
|
||||||
|
keyboardController?.hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
focusRequester.requestFocus()
|
||||||
|
keyboardController?.hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encabezados
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 8.dp),
|
||||||
|
horizontalArrangement = Arrangement.SpaceEvenly
|
||||||
|
) {
|
||||||
|
headers.forEach { text ->
|
||||||
|
Text(
|
||||||
|
text = text,
|
||||||
|
color = Color.White,
|
||||||
|
fontSize = 14.sp,
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HorizontalDivider(thickness = 1.dp, color = Color.White)
|
||||||
|
|
||||||
|
LazyColumn(modifier = Modifier.fillMaxSize()) {
|
||||||
|
items(items) { item ->
|
||||||
|
GenericRow(
|
||||||
|
values = item,
|
||||||
|
onLongClick = { onLongClick(item) },
|
||||||
|
onClick = { onClick(item) },
|
||||||
|
columnActions = columnActions
|
||||||
|
)
|
||||||
|
HorizontalDivider(thickness = 1.dp, color = Color.White)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
showLoading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
|
@Composable
|
||||||
|
fun GenericRow(
|
||||||
|
values: List<String>,
|
||||||
|
onLongClick: () -> Unit,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
columnActions: List<(List<String>) -> Unit>
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 8.dp)
|
||||||
|
.combinedClickable(onClick = onClick, onLongClick = onLongClick),
|
||||||
|
horizontalArrangement = Arrangement.SpaceEvenly
|
||||||
|
) {
|
||||||
|
values.forEachIndexed { index, value ->
|
||||||
|
val sdf = SimpleDateFormat(stringResource(R.string.dateFormat), Locale.getDefault())
|
||||||
|
val currentDate = sdf.format(Date())
|
||||||
|
|
||||||
|
val context = LocalContext.current // Accediendo al contexto
|
||||||
|
|
||||||
|
val customOrange = ContextCompat.getColor(context, R.color.verdnatura_pumpkin_orange)
|
||||||
|
val customWhite = ContextCompat.getColor(context, R.color.verdnatura_white)
|
||||||
|
val color = if (value == currentDate) Color(customOrange) else Color(customWhite)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = value,
|
||||||
|
color = color,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f)
|
||||||
|
.then(if (index < columnActions.size) Modifier.clickable {
|
||||||
|
columnActions[index](values)
|
||||||
|
} else Modifier)
|
||||||
|
.align(Alignment.CenterVertically)
|
||||||
|
.padding(4.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TextDayOfSale(
|
||||||
|
values: List<String>,
|
||||||
|
value: String,
|
||||||
|
index: Int,
|
||||||
|
columnActions: List<(List<String>) -> Unit>
|
||||||
|
) {
|
||||||
|
val sdf = SimpleDateFormat(stringResource(R.string.dateFormat), Locale.getDefault())
|
||||||
|
val currentDate = sdf.format(Date())
|
||||||
|
|
||||||
|
val context = LocalContext.current
|
||||||
|
val customOrange = ContextCompat.getColor(context, R.color.verdnatura_pumpkin_orange)
|
||||||
|
val customWhite = ContextCompat.getColor(context, R.color.verdnatura_white)
|
||||||
|
val color = if (value == currentDate) Color(customOrange) else Color(customWhite)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = value,
|
||||||
|
color = color,
|
||||||
|
modifier = Modifier
|
||||||
|
.then(if (index < columnActions.size) Modifier.clickable {
|
||||||
|
columnActions[index](values)
|
||||||
|
} else Modifier)
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
package es.verdnatura.presentation.view.feature.paletizador.fragment
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.activity.OnBackPressedCallback
|
||||||
|
import androidx.activity.OnBackPressedDispatcher
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.ui.platform.ComposeView
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
|
import es.verdnatura.R
|
||||||
|
import es.verdnatura.presentation.common.OnBackPressedListener
|
||||||
|
import es.verdnatura.presentation.view.component.CustomDialogListComposable
|
||||||
|
import es.verdnatura.presentation.view.feature.main.activity.MainActivity
|
||||||
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
|
|
||||||
|
class ExpeditionScanSorterFragmentCompose(
|
||||||
|
var title: String = ""
|
||||||
|
) : Fragment(), OnBackPressedListener {
|
||||||
|
private val viewModel: ExpeditionScanSorterViewModelCompose by viewModel()
|
||||||
|
private lateinit var backDispatcher: OnBackPressedDispatcher
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun newInstance(title: String) = ExpeditionScanSorterFragmentCompose(title)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
val composeView = ComposeView(requireContext())
|
||||||
|
|
||||||
|
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner,
|
||||||
|
object : OnBackPressedCallback(true) {
|
||||||
|
override fun handleOnBackPressed() {
|
||||||
|
(activity as? MainActivity)?.onMyBackPressed()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
composeView.setContent {
|
||||||
|
SetComposableView()
|
||||||
|
}
|
||||||
|
|
||||||
|
return composeView
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun SetComposableView() {
|
||||||
|
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
||||||
|
CustomDialogListComposable(
|
||||||
|
title = getString(R.string.expeditionNoSorter),
|
||||||
|
onOkClick = { (context as MainActivity).onMyBackPressed() },
|
||||||
|
showRecyclerView = true,
|
||||||
|
buttonOkText = getString(R.string.end),
|
||||||
|
recyclerViewItems = uiState.items,
|
||||||
|
onEnterPressed = { text ->
|
||||||
|
if (text.isNotEmpty()) try {
|
||||||
|
viewModel.expeditionScan(text.toLong())
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
(context as MainActivity).messageWithSound(
|
||||||
|
message = getString(R.string.errorInput),
|
||||||
|
isPlayed = true,
|
||||||
|
isToasted = true,
|
||||||
|
isError = true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBackPressedHandled(): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
(activity as? MainActivity)?.onMyBackPressed()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package es.verdnatura.presentation.view.feature.paletizador.fragment
|
||||||
|
|
||||||
|
import es.verdnatura.domain.SalixCallback
|
||||||
|
import es.verdnatura.presentation.base.BaseViewModelCompose
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.flow.update
|
||||||
|
import retrofit2.Response
|
||||||
|
|
||||||
|
data class UiState(
|
||||||
|
var items: MutableList<Number> = mutableListOf(),
|
||||||
|
val isLoading: Boolean = false
|
||||||
|
)
|
||||||
|
|
||||||
|
class ExpeditionScanSorterViewModelCompose(var application: android.app.Application) :
|
||||||
|
BaseViewModelCompose(application) {
|
||||||
|
|
||||||
|
private val _uiState = MutableStateFlow(UiState())
|
||||||
|
val uiState = _uiState.asStateFlow()
|
||||||
|
|
||||||
|
fun expeditionScan(vExpeditionId: Number) {
|
||||||
|
salix.expeditionScan(params = arrayListOf(vExpeditionId))
|
||||||
|
.enqueue(object : SalixCallback<Unit>(application.applicationContext) {
|
||||||
|
override fun onSuccess(response: Response<Unit>) {
|
||||||
|
super.onSuccess(response)
|
||||||
|
|
||||||
|
_uiState.update { currentState ->
|
||||||
|
currentState.copy(
|
||||||
|
items = currentState.items.toMutableList().apply { add(vExpeditionId) },
|
||||||
|
isLoading = false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(t: Throwable) {
|
||||||
|
super.onError(t)
|
||||||
|
_uiState.update { it.copy(isLoading = false) }
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -41,7 +41,7 @@
|
||||||
<dimen name="item_list_separation">4dp</dimen>
|
<dimen name="item_list_separation">4dp</dimen>
|
||||||
|
|
||||||
<!--text toolbar-->
|
<!--text toolbar-->
|
||||||
<dimen name="title">18sp</dimen>
|
<dimen name="title">20sp</dimen>
|
||||||
<dimen name="subtitle">16sp</dimen>
|
<dimen name="subtitle">16sp</dimen>
|
||||||
|
|
||||||
<!--Text sizes-->
|
<!--Text sizes-->
|
||||||
|
|
Loading…
Reference in New Issue