Scan to open on your phone
Point a camera at the QR code - it opens this exact paste, no app needed.
https://codepastes.com/zzgs9bfhnacy4hf5untitledPlain Text
package com.negocio.desinfectantes.ui.inactivos
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.Restore
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.negocio.desinfectantes.data.*
private val CardBlue = Color(0xFF1B2D4A)
private val AccentBlue = Color(0xFF2585F5)
private val SoftBlue = Color(0xFFA9BEDB)
@Composable
fun RegistrosInactivosScreen(
productos: List<ProductoEntity>,
aromas: List<AromaEntity>,
presentaciones: List<PresentacionEntity>,
todosProductos: List<ProductoEntity>,
todosAromas: List<AromaEntity>,
onVolver: () -> Unit,
onReactivarProducto: (ProductoEntity) -> Unit,
onReactivarAroma: (AromaEntity) -> Unit,
onReactivarPresentacion: (PresentacionEntity) -> Unit
) {
var categoria by remember { mutableStateOf("Productos") }
Column(
modifier = Modifier
.fillMaxSize()
.padding(20.dp)
) {
Row(verticalAlignment = Alignment.CenterVertically) {
IconButton(onClick = onVolver) {
Icon(
Icons.Default.ArrowBack,
contentDescription = "Volver",
tint = Color.White
)
}
Text(
"Registros inactivos",
color = Color.White,
style = MaterialTheme.typography.headlineSmall
)
}
Spacer(modifier = Modifier.height(16.dp))
SingleChoiceSegmentedButtonRow(
modifier = Modifier.fillMaxWidth()
) {
listOf("Productos", "Aromas", "Presentaciones")
.forEachIndexed { index, nombre ->
SegmentedButton(
selected = categoria == nombre,
onClick = { categoria = nombre },
shape = SegmentedButtonDefaults.itemShape(
index = index,
count = 3
)
) {
Text(
nombre,
style = MaterialTheme.typography.labelSmall
)
}
}
}
Spacer(modifier = Modifier.height(16.dp))
when (categoria) {
"Productos" -> {
if (productos.isEmpty()) {
MensajeVacio("No hay productos inactivos")
} else {
LazyColumn(
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
items(productos) { producto ->
TarjetaInactiva(
nombre = producto.nombre,
detalle = "Producto inactivo",
icono = "🧴",
onReactivar = {
onReactivarProducto(producto)
}
)
}
}
}
}
"Aromas" -> {
if (aromas.isEmpty()) {
MensajeVacio("No hay aromas inactivos")
} else {
LazyColumn(
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
items(aromas) { aroma ->
val nombreProducto = todosProductos
.find { it.id == aroma.productoId }
?.nombre ?: "Producto no encontrado"
TarjetaInactiva(
nombre = aroma.nombre,
detalle = "Producto: $nombreProducto",
icono = "🌸",
onReactivar = {
onReactivarAroma(aroma)
}
)
}
}
}
}
"Presentaciones" -> {
if (presentaciones.isEmpty()) {
MensajeVacio("No hay presentaciones inactivas")
} else {
LazyColumn(
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
items(presentaciones) { presentacion ->
val aroma = todosAromas.find {
it.id == presentacion.aromaId
}
val producto = todosProductos.find {
it.id == aroma?.productoId
}
TarjetaInactiva(
nombre = presentacion.nombre,
detalle = "${producto?.nombre ?: "Producto desconocido"} • ${aroma?.nombre ?: "Aroma desconocido"}",
icono = "📦",
onReactivar = {
onReactivarPresentacion(presentacion)
}
)
}
}
}
}
}
}
}
@Composable
private fun MensajeVacio(mensaje: String) {
Card(
modifier = Modifier.fillMaxWidth(),
colors = CardDefaults.cardColors(
containerColor = CardBlue
),
shape = RoundedCornerShape(18.dp)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(24.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("📦", style = MaterialTheme.typography.displayMedium)
Spacer(modifier = Modifier.height(12.dp))
Text(
mensaje,
color = Color.White,
style = MaterialTheme.typography.titleMedium
)
}
}
}
@Composable
private fun TarjetaInactiva(
nombre: String,
detalle: String,
icono: String,
onReactivar: () -> Unit
) {
Card(
modifier = Modifier.fillMaxWidth(),
colors = CardDefaults.cardColors(
containerColor = CardBlue
),
shape = RoundedCornerShape(18.dp)
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
icono,
style = MaterialTheme.typography.headlineMedium
)
Spacer(modifier = Modifier.width(14.dp))
Column(
modifier = Modifier.weight(1f)
) {
Text(
nombre,
color = Color.White,
style = MaterialTheme.typography.titleMedium
)
Text(
detalle,
color = SoftBlue,
style = MaterialTheme.typography.bodySmall
)
}
IconButton(onClick = onReactivar) {
Icon(
Icons.Default.Restore,
contentDescription = "Reactivar",
tint = AccentBlue
)
}
}
}
}
package com.negocio.desinfectantes.ui.productos
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.background
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.Save
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import com.negocio.desinfectantes.data.PresentacionEntity
private val Navy = Color(0xFF101D35)
private val CardBlue = Color(0xFF1B2D4A)
private val AccentBlue = Color(0xFF2585F5)
private val SoftBlue = Color(0xFFA9BEDB)
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun EditarPresentacionScreen(
nombreProducto: String,
nombreAroma: String,
presentacion: PresentacionEntity,
onVolver: () -> Unit,
onGuardar: (String, Int, Double) -> Unit,
onEliminar: () -> Unit
) {
var nombre by remember(presentacion.id) {
mutableStateOf(presentacion.nombre)
}
var contenido by remember(presentacion.id) {
mutableStateOf(presentacion.contenidoMl.toString())
}
var precio by remember(presentacion.id) {
mutableStateOf(
presentacion.precio.toString().removeSuffix(".0")
)
}
var mostrarConfirmacionEliminar by remember {
mutableStateOf(false)
}
val contenidoValido = contenido.toIntOrNull()?.let { it > 0 } ?: false
val precioValido = precio.toDoubleOrNull()?.let { it >= 0 } ?: false
Column(
modifier = Modifier
.fillMaxSize()
.background(Navy)
.verticalScroll(rememberScrollState())
.padding(20.dp)
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Start
) {
IconButton(onClick = onVolver) {
Icon(
imageVector = Icons.Default.ArrowBack,
contentDescription = "Volver",
tint = Color.White
)
}
}
Spacer(modifier = Modifier.height(10.dp))
Text(
text = "Editar presentación",
color = Color.White,
style = MaterialTheme.typography.headlineSmall
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "$nombreProducto • $nombreAroma",
color = SoftBlue,
style = MaterialTheme.typography.bodyMedium
)
Spacer(modifier = Modifier.height(24.dp))
OutlinedTextField(
value = nombre,
onValueChange = { nombre = it },
label = { Text("Nombre de la presentación") },
modifier = Modifier.fillMaxWidth(),
singleLine = true,
colors = OutlinedTextFieldDefaults.colors(
focusedTextColor = Color.White,
unfocusedTextColor = Color.White,
focusedBorderColor = AccentBlue,
unfocusedBorderColor = SoftBlue,
focusedLabelColor = AccentBlue,
unfocusedLabelColor = SoftBlue,
cursorColor = AccentBlue
)
)
Spacer(modifier = Modifier.height(16.dp))
OutlinedTextField(
value = contenido,
onValueChange = { contenido = it },
label = { Text("Contenido en mililitros (ml)") },
modifier = Modifier.fillMaxWidth(),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Number
),
colors = OutlinedTextFieldDefaults.colors(
focusedTextColor = Color.White,
unfocusedTextColor = Color.White,
focusedBorderColor = AccentBlue,
unfocusedBorderColor = SoftBlue,
focusedLabelColor = AccentBlue,
unfocusedLabelColor = SoftBlue,
cursorColor = AccentBlue
)
)
Spacer(modifier = Modifier.height(16.dp))
OutlinedTextField(
value = precio,
onValueChange = { precio = it },
label = { Text("Precio de venta") },
modifier = Modifier.fillMaxWidth(),
singleLine = true,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Decimal
),
colors = OutlinedTextFieldDefaults.colors(
focusedTextColor = Color.White,
unfocusedTextColor = Color.White,
focusedBorderColor = AccentBlue,
unfocusedBorderColor = SoftBlue,
focusedLabelColor = AccentBlue,
unfocusedLabelColor = SoftBlue,
cursorColor = AccentBlue
)
)
Spacer(modifier = Modifier.height(28.dp))
Button(
onClick = {
onGuardar(
nombre.trim(),
contenido.toInt(),
precio.toDouble()
)
},
modifier = Modifier
.fillMaxWidth()
.height(54.dp),
enabled = nombre.isNotBlank() && contenidoValido && precioValido,
colors = ButtonDefaults.buttonColors(
containerColor = AccentBlue
)
) {
Icon(
imageVector = Icons.Default.Save,
contentDescription = null
)
Spacer(modifier = Modifier.width(8.dp))
Text("Guardar cambios")
}
Spacer(modifier = Modifier.height(14.dp))
OutlinedButton(
onClick = {
mostrarConfirmacionEliminar = true
},
modifier = Modifier
.fillMaxWidth()
.height(54.dp),
colors = ButtonDefaults.outlinedButtonColors(
contentColor = Color.Red
)
) {
Icon(
imageVector = Icons.Default.Delete,
contentDescription = null
)
Spacer(modifier = Modifier.width(8.dp))
Text("Eliminar presentación")
}
}
if (mostrarConfirmacionEliminar) {
AlertDialog(
onDismissRequest = {
mostrarConfirmacionEliminar = false
},
title = {
Text("Eliminar presentación")
},
text = {
Text(
"¿Estás seguro de que deseas eliminar " +
"${presentacion.nombre}? Esta acción no se puede deshacer."
)
},
confirmButton = {
TextButton(
onClick = {
mostrarConfirmacionEliminar = false
onEliminar()
}
) {
Text(
"Eliminar",
color = Color.Red
)
}
},
dismissButton = {
TextButton(
onClick = {
mostrarConfirmacionEliminar = false
}
) {
Text("Cancelar")
}
}
)
}
}
15,650 chars · codepastes.com